Passed
Pull Request — dev (#8)
by Rafael
58:47
created

Societe::setMysoc()   F

Complexity

Conditions 23
Paths > 20000

Size

Total Lines 123
Code Lines 91

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 23
eloc 91
nc 622080
nop 1
dl 0
loc 123
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

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

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

936
        $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...
937
        $this->setUpperOrLowerCase();
938
        $this->nom = $this->name; // For backward compatibility
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

938
        /** @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...
939
        if (empty($this->client)) {
940
            $this->client = 0;
941
        }
942
        if (empty($this->fournisseur)) {
943
            $this->fournisseur = 0;
944
        }
945
        $this->import_key = trim((string) $this->import_key);
946
947
        $this->accountancy_code_customer = trim((string) $this->code_compta);
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Cl...s\Societe::$code_compta has been deprecated: Use $code_compta_client ( Ignorable by Annotation )

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

947
        $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...
948
        $this->accountancy_code_supplier = trim((string) $this->code_compta_fournisseur);
949
        $this->accountancy_code_buy = trim((string) $this->accountancy_code_buy);
950
        $this->accountancy_code_sell = trim((string) $this->accountancy_code_sell);
951
952
        if (!empty($this->multicurrency_code)) {
953
            $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code);
954
        }
955
        if (empty($this->fk_multicurrency)) {
956
            $this->multicurrency_code = '';
957
            $this->fk_multicurrency = 0;
958
        }
959
960
        dol_syslog(get_class($this) . "::create " . $this->name);
961
962
        $now = dol_now();
963
964
        if (empty($this->date_creation)) {
965
            $this->date_creation = $now;
966
        }
967
968
        $this->db->begin();
969
970
        // For automatic creation during create action (not used by Dolibarr GUI, can be used by scripts)
971
        if ($this->code_client == -1 || $this->code_client === 'auto') {
972
            $this->get_codeclient($this, 0);
973
        }
974
        if ($this->code_fournisseur == '-1' || $this->code_fournisseur === 'auto') {
975
            $this->get_codefournisseur($this, 1);
976
        }
977
978
        // Check more parameters (including mandatory setup
979
        // If error, this->errors[] is filled
980
        $result = $this->verify();
981
982
        if ($result >= 0) {
983
            $this->entity = ((isset($this->entity) && is_numeric($this->entity)) ? $this->entity : $conf->entity);
984
985
            $sql = "INSERT INTO " . MAIN_DB_PREFIX . "societe (";
986
            $sql .= "nom";
987
            $sql .= ", name_alias";
988
            $sql .= ", entity";
989
            $sql .= ", datec";
990
            $sql .= ", fk_user_creat";
991
            $sql .= ", fk_typent";
992
            $sql .= ", canvas";
993
            $sql .= ", status";
994
            $sql .= ", ref_ext";
995
            $sql .= ", fk_stcomm";
996
            $sql .= ", fk_incoterms";
997
            $sql .= ", location_incoterms";
998
            $sql .= ", import_key";
999
            $sql .= ", fk_multicurrency";
1000
            $sql .= ", multicurrency_code";
1001
            if (!getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
1002
                $sql .= ", vat_reverse_charge";
1003
                $sql .= ", accountancy_code_buy";
1004
                $sql .= ", accountancy_code_sell";
1005
            }
1006
            $sql .= ") VALUES ('" . $this->db->escape($this->name) . "',";
1007
            $sql .= " '" . $this->db->escape($this->name_alias) . "',";
1008
            $sql .= " " . ((int) $this->entity) . ",";
1009
            $sql .= " '" . $this->db->idate($this->date_creation) . "'";
1010
            $sql .= ", " . (!empty($user->id) ? ((int) $user->id) : "null");
1011
            $sql .= ", " . (!empty($this->typent_id) ? ((int) $this->typent_id) : "null");
1012
            $sql .= ", " . (!empty($this->canvas) ? "'" . $this->db->escape($this->canvas) . "'" : "null");
1013
            $sql .= ", " . ((int) $this->status);
1014
            $sql .= ", " . (!empty($this->ref_ext) ? "'" . $this->db->escape($this->ref_ext) . "'" : "null");
1015
            $sql .= ", 0";
1016
            $sql .= ", " . (int) $this->fk_incoterms;
1017
            $sql .= ", '" . $this->db->escape($this->location_incoterms) . "'";
1018
            $sql .= ", " . (!empty($this->import_key) ? "'" . $this->db->escape($this->import_key) . "'" : "null");
1019
            $sql .= ", " . (int) $this->fk_multicurrency;
1020
            $sql .= ", '" . $this->db->escape($this->multicurrency_code) . "'";
1021
            if (!getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
1022
                $sql .= ", " . (empty($this->vat_reverse_charge) ? '0' : '1');
1023
                $sql .= ", '" . $this->db->escape($this->accountancy_code_buy) . "'";
1024
                $sql .= ", '" . $this->db->escape($this->accountancy_code_sell) . "'";
1025
            }
1026
            $sql .= ")";
1027
1028
            dol_syslog(get_class($this) . "::create", LOG_DEBUG);
1029
1030
            $result = $this->db->query($sql);
1031
            if ($result) {
1032
                $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "societe");
1033
1034
                $ret = $this->update($this->id, $user, 0, 1, 1, 'add');
1035
1036
                // update accountancy for this entity
1037
                if (!$error && getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
1038
                    $this->db->query("DELETE FROM " . MAIN_DB_PREFIX . "societe_perentity WHERE fk_soc = " . ((int) $this->id) . " AND entity = " . ((int) $conf->entity));
1039
1040
                    $sql = "INSERT INTO " . MAIN_DB_PREFIX . "societe_perentity (";
1041
                    $sql .= " fk_soc";
1042
                    $sql .= ", entity";
1043
                    $sql .= ", vat_reverse_charge";
1044
                    $sql .= ", accountancy_code_customer";
1045
                    $sql .= ", accountancy_code_supplier";
1046
                    $sql .= ", accountancy_code_buy";
1047
                    $sql .= ", accountancy_code_sell";
1048
                    $sql .= ") VALUES (";
1049
                    $sql .= $this->id;
1050
                    $sql .= ", " . ((int) $conf->entity);
1051
                    $sql .= ", " . (empty($this->vat_reverse_charge) ? '0' : '1');
1052
                    $sql .= ", '" . $this->db->escape($this->accountancy_code_customer) . "'";
1053
                    $sql .= ", '" . $this->db->escape($this->accountancy_code_supplier) . "'";
1054
                    $sql .= ", '" . $this->db->escape($this->accountancy_code_buy) . "'";
1055
                    $sql .= ", '" . $this->db->escape($this->accountancy_code_sell) . "'";
1056
                    $sql .= ")";
1057
                    $result = $this->db->query($sql);
1058
                    if (!$result) {
1059
                        $error++;
1060
                        $this->error = 'ErrorFailedToUpdateAccountancyForEntity';
1061
                    }
1062
                }
1063
1064
                // Ajout du commercial affecte
1065
                if ($this->commercial_id != '' && $this->commercial_id != -1) {
1066
                    $this->add_commercial($user, $this->commercial_id);
1067
                } elseif (!$user->hasRight('societe', 'client', 'voir')) {
1068
                    // si un commercial cree un client il lui est affecte automatiquement
1069
                    $this->add_commercial($user, $user->id);
1070
                }
1071
1072
                if ($ret >= 0) {
1073
                    if (! $notrigger) {
1074
                        // Call trigger
1075
                        $result = $this->call_trigger('COMPANY_CREATE', $user);
1076
                        if ($result < 0) {
1077
                            $error++;
1078
                        }
1079
                        // End call triggers
1080
                    }
1081
                } else {
1082
                    $error++;
1083
                }
1084
1085
                if (!$error) {
1086
                    dol_syslog(get_class($this) . "::Create success id=" . $this->id);
1087
                    $this->db->commit();
1088
                    return $this->id;
1089
                } else {
1090
                    dol_syslog(get_class($this) . "::Create echec update " . $this->error . (empty($this->errors) ? '' : ' ' . implode(',', $this->errors)), LOG_ERR);
1091
                    $this->db->rollback();
1092
                    return -4;
1093
                }
1094
            } else {
1095
                if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
1096
                    $this->error = $langs->trans("ErrorCompanyNameAlreadyExists", $this->name); // duplicate on a field (code or profid or ...)
1097
                    $result = -1;
1098
                } else {
1099
                    $this->error = $this->db->lasterror();
1100
                    $result = -2;
1101
                }
1102
                $this->db->rollback();
1103
                return $result;
1104
            }
1105
        } else {
1106
            $this->db->rollback();
1107
            dol_syslog(get_class($this) . "::Create fails verify " . implode(',', $this->errors), LOG_WARNING);
1108
            return -3;
1109
        }
1110
    }
1111
1112
1113
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1114
    /**
1115
     * Create a contact/address from thirdparty
1116
     *
1117
     * @param   User    $user           Object user
1118
     * @param   int     $no_email       1=Do not send mailing, 0=Ok to receive mailing
1119
     * @param   array   $tags           Array of tag to affect to contact
1120
     * @param   int     $notrigger      1=Does not execute triggers, 0= execute triggers
1121
     * @return  int                     Return integer <0 if KO, >0 if OK
1122
     */
1123
    public function create_individual(User $user, $no_email = 0, $tags = array(), $notrigger = 0)
1124
    {
1125
        global $conf;
1126
1127
        $error = 0;
1128
1129
        $this->db->begin();
1130
1131
        $contact = new Contact($this->db);
1132
1133
        $contact->name              = $this->name_bis;
1134
        $contact->firstname         = $this->firstname;
1135
        $contact->civility_id       = $this->civility_id;
1136
        $contact->socid             = $this->id; // fk_soc
1137
        $contact->statut            = 1; // deprecated
1138
        $contact->status            = 1;
1139
        $contact->priv              = 0;
1140
        $contact->country_id        = $this->country_id;
1141
        $contact->state_id          = $this->state_id;
1142
        $contact->address           = $this->address;
1143
        $contact->email             = $this->email;
1144
        $contact->zip               = $this->zip;
1145
        $contact->town              = $this->town;
1146
        $this->setUpperOrLowerCase();
1147
        $contact->phone_pro         = $this->phone;
1148
1149
        $contactId = $contact->create($user, $notrigger);
1150
        if ($contactId < 0) {
1151
            $error++;
1152
            $this->error = $contact->error;
1153
            $this->errors = $contact->errors;
1154
            dol_syslog(get_class($this) . "::create_individual ERROR:" . $this->error, LOG_ERR);
1155
        }
1156
1157
        if (empty($error) && is_array($tags) && !empty($tags)) {
1158
            $result = $contact->setCategories($tags);
1159
            if ($result < 0) {
1160
                $error++;
1161
                $this->error = $contact->error;
1162
                $this->errors = array_merge($this->errors, $contact->errors);
1163
                dol_syslog(get_class($this) . "::create_individual Affect Tag ERROR:" . $this->error, LOG_ERR);
1164
                $contactId = $result;
1165
            }
1166
        }
1167
1168
        if (empty($error) && isModEnabled('mailing') && !empty($contact->email) && isset($no_email)) {
1169
            $result = $contact->setNoEmail($no_email);
1170
            if ($result < 0) {
1171
                $this->error = $contact->error;
1172
                $this->errors = array_merge($this->errors, $contact->errors);
1173
                dol_syslog(get_class($this) . "::create_individual set mailing status ERROR:" . $this->error, LOG_ERR);
1174
                $contactId = $result;
1175
            }
1176
        }
1177
1178
        if (empty($error)) {
1179
            dol_syslog(get_class($this) . "::create_individual success");
1180
            $this->db->commit();
1181
        } else {
1182
            $this->db->rollback();
1183
        }
1184
1185
        return $contactId;
1186
    }
1187
1188
    /**
1189
     *    Check properties of third party are ok (like name, third party codes, ...)
1190
     *    Used before an add or update.
1191
     *
1192
     *    @return     int       0 if OK, <0 if KO
1193
     */
1194
    public function verify()
1195
    {
1196
        global $conf, $langs, $mysoc;
1197
1198
        $error = 0;
1199
        $this->errors = array();
1200
1201
        $result = 0;
1202
        $this->name = trim($this->name);
1203
        $this->nom = $this->name; // For backward compatibility
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

1203
        /** @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...
1204
1205
        if (!$this->name) {
1206
            $this->errors[] = 'ErrorBadThirdPartyName';
1207
            $result = -2;
1208
        }
1209
1210
        if ($this->client) {
1211
            $rescode = $this->check_codeclient();
1212
            if ($rescode != 0 && $rescode != -5) {
1213
                if ($rescode == -1) {
1214
                    $this->errors[] = 'ErrorBadCustomerCodeSyntax';
1215
                } elseif ($rescode == -2) {
1216
                    $this->errors[] = 'ErrorCustomerCodeRequired';
1217
                } elseif ($rescode == -3) {
1218
                    $this->errors[] = 'ErrorCustomerCodeAlreadyUsed';
1219
                } elseif ($rescode == -4) {
1220
                    $this->errors[] = 'ErrorPrefixRequired';
1221
                } else {
1222
                    $this->errors[] = 'ErrorUnknownOnCustomerCodeCheck';
1223
                }
1224
1225
                $result = -3;
1226
            }
1227
        }
1228
1229
        if ($this->fournisseur) {
1230
            $rescode = $this->check_codefournisseur();
1231
            if ($rescode != 0 && $rescode != -5) {
1232
                if ($rescode == -1) {
1233
                    $this->errors[] = 'ErrorBadSupplierCodeSyntax';
1234
                } elseif ($rescode == -2) {
1235
                    $this->errors[] = 'ErrorSupplierCodeRequired';
1236
                } elseif ($rescode == -3) {
1237
                    $this->errors[] = 'ErrorSupplierCodeAlreadyUsed';
1238
                } elseif ($rescode == -4) {
1239
                    $this->errors[] = 'ErrorPrefixRequired';
1240
                } else {
1241
                    $this->errors[] = 'ErrorUnknownOnSupplierCodeCheck';
1242
                }
1243
                $result = -3;
1244
            }
1245
        }
1246
1247
        // Check for duplicate or mandatory fields defined into setup
1248
        $array_to_check = array('IDPROF1', 'IDPROF2', 'IDPROF3', 'IDPROF4', 'IDPROF5', 'IDPROF6', 'EMAIL', 'TVA_INTRA', 'ACCOUNTANCY_CODE_CUSTOMER', 'ACCOUNTANCY_CODE_SUPPLIER');
1249
        foreach ($array_to_check as $key) {
1250
            $keymin = strtolower($key);
1251
            if ($key == 'ACCOUNTANCY_CODE_CUSTOMER') {
1252
                $keymin = 'code_compta';
1253
            } elseif ($key == 'ACCOUNTANCY_CODE_SUPPLIER') {
1254
                $keymin = 'code_compta_fournisseur';
1255
            }
1256
            $i = (int) preg_replace('/[^0-9]/', '', $key);
1257
            $vallabel = $this->$keymin;
1258
1259
            if ($i > 0) {
1260
                if ($this->isACompany()) {
1261
                    // Check for mandatory prof id (but only if country is same than ours)
1262
                    if ($mysoc->country_id > 0 && $this->country_id == $mysoc->country_id) {
1263
                        $idprof_mandatory = 'SOCIETE_' . $key . '_MANDATORY';
1264
                        if (!$vallabel && getDolGlobalString($idprof_mandatory)) {
1265
                            $langs->load("errors");
1266
                            $error++;
1267
                            $this->errors[] = $langs->trans("ErrorProdIdIsMandatory", $langs->transcountry('ProfId' . $i, $this->country_code)) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
1268
                        }
1269
                    }
1270
                }
1271
1272
                // Check for unicity on profid
1273
                if (!$error && $vallabel && $this->id_prof_verifiable($i)) {
1274
                    if ($this->id_prof_exists($keymin, $vallabel, ($this->id > 0 ? $this->id : 0))) {
1275
                        $langs->load("errors");
1276
                        $error++;
1277
                        $this->errors[] = $langs->transcountry('ProfId' . $i, $this->country_code) . " " . $langs->trans("ErrorProdIdAlreadyExist", $vallabel) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
1278
                    }
1279
                }
1280
            } else {
1281
                //var_dump($conf->global->SOCIETE_EMAIL_UNIQUE);
1282
                //var_dump($conf->global->SOCIETE_EMAIL_MANDATORY);
1283
                if ($key == 'EMAIL') {
1284
                    // Check for mandatory
1285
                    if (getDolGlobalString('SOCIETE_EMAIL_MANDATORY') && !isValidEmail($this->email)) {
1286
                        $langs->load("errors");
1287
                        $error++;
1288
                        $this->errors[] = $langs->trans("ErrorBadEMail", $this->email) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
1289
                    }
1290
1291
                    // Check for unicity
1292
                    if (!$error && $vallabel && getDolGlobalString('SOCIETE_EMAIL_UNIQUE')) {
1293
                        if ($this->id_prof_exists($keymin, $vallabel, ($this->id > 0 ? $this->id : 0))) {
1294
                            $langs->load("errors");
1295
                            $error++;
1296
                            $this->errors[] = $langs->trans('Email') . " " . $langs->trans("ErrorProdIdAlreadyExist", $vallabel) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
1297
                        }
1298
                    }
1299
                } elseif ($key == 'TVA_INTRA') {
1300
                    // Check for unicity
1301
                    if ($vallabel && getDolGlobalString('SOCIETE_VAT_INTRA_UNIQUE')) {
1302
                        if ($this->id_prof_exists($keymin, $vallabel, ($this->id > 0 ? $this->id : 0))) {
1303
                            $langs->load("errors");
1304
                            $error++;
1305
                            $this->errors[] = $langs->trans('VATIntra') . " " . $langs->trans("ErrorProdIdAlreadyExist", $vallabel) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
1306
                        }
1307
                    }
1308
                } elseif ($key == 'ACCOUNTANCY_CODE_CUSTOMER' && !empty($this->client)) {
1309
                    // Check for unicity
1310
                    if ($vallabel && getDolGlobalString('SOCIETE_ACCOUNTANCY_CODE_CUSTOMER_UNIQUE')) {
1311
                        if ($this->id_prof_exists($keymin, $vallabel, ($this->id > 0 ? $this->id : 0))) {
1312
                            $langs->loadLangs(array("errors", 'compta'));
1313
                            $error++;
1314
                            $this->errors[] = $langs->trans('CustomerAccountancyCodeShort') . " " . $langs->trans("ErrorProdIdAlreadyExist", $vallabel) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
1315
                        }
1316
                    }
1317
1318
                    // Check for mandatory
1319
                    if (getDolGlobalString('SOCIETE_ACCOUNTANCY_CODE_CUSTOMER_MANDATORY') && (!isset($vallabel) || trim($vallabel) === '')) {
1320
                        $langs->loadLangs(array("errors", 'compta'));
1321
                        $error++;
1322
                        $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv('CustomerAccountancyCodeShort')) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
1323
                    }
1324
                } elseif ($key == 'ACCOUNTANCY_CODE_SUPPLIER' && !empty($this->fournisseur)) {
1325
                    // Check for unicity
1326
                    if ($vallabel && getDolGlobalString('SOCIETE_ACCOUNTANCY_CODE_SUPPLIER_UNIQUE')) {
1327
                        if ($this->id_prof_exists($keymin, $vallabel, ($this->id > 0 ? $this->id : 0))) {
1328
                            $langs->loadLangs(array("errors", 'compta'));
1329
                            $error++;
1330
                            $this->errors[] = $langs->trans('SupplierAccountancyCodeShort') . " " . $langs->trans("ErrorProdIdAlreadyExist", $vallabel) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
1331
                        }
1332
                    }
1333
1334
                    // Check for mandatory
1335
                    if (getDolGlobalString('SOCIETE_ACCOUNTANCY_CODE_SUPPLIER_MANDATORY') && (!isset($vallabel) || trim($vallabel) === '')) {
1336
                        $langs->loadLangs(array("errors", 'compta'));
1337
                        $error++;
1338
                        $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv('SupplierAccountancyCodeShort')) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
1339
                    }
1340
                }
1341
            }
1342
        }
1343
1344
        if ($error) {
1345
            $result = -4;
1346
        }
1347
1348
        return $result;
1349
    }
1350
1351
    /**
1352
     *      Update parameters of third party
1353
     *
1354
     *      @param  int     $id                         Id of company (deprecated, use 0 here and call update on an object loaded by a fetch)
1355
     *      @param  User    $user                       User who requests the update
1356
     *      @param  int     $call_trigger               0=no, 1=yes
1357
     *      @param  int     $allowmodcodeclient         Inclut modif code client et code compta
1358
     *      @param  int     $allowmodcodefournisseur    Inclut modif code fournisseur et code compta fournisseur
1359
     *      @param  string  $action                     'add' or 'update' or 'merge'
1360
     *      @param  int     $nosyncmember               Do not synchronize info of linked member
1361
     *      @return int                                 Return integer <0 if KO, >=0 if OK
1362
     */
1363
    public function update($id, User $user, $call_trigger = 1, $allowmodcodeclient = 0, $allowmodcodefournisseur = 0, $action = 'update', $nosyncmember = 1)
1364
    {
1365
        global $langs, $conf, $hookmanager;
1366
1367
        require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/functions2.lib.php';
1368
1369
        if (empty($id)) {
1370
            $id = $this->id;
1371
        }
1372
1373
        $error = 0;
1374
1375
        dol_syslog(get_class($this) . "::Update id=" . $id . " call_trigger=" . $call_trigger . " allowmodcodeclient=" . $allowmodcodeclient . " allowmodcodefournisseur=" . $allowmodcodefournisseur);
1376
1377
        $now = dol_now();
1378
1379
        // Clean parameters
1380
        $this->id           = $id;
1381
        $this->entity       = ((isset($this->entity) && is_numeric($this->entity)) ? $this->entity : $conf->entity);
1382
        $this->name         = $this->name ? trim($this->name) : trim((string) $this->nom);
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

1382
        $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...
1383
        $this->nom          = $this->name; // For backward compatibility
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

1383
        /** @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...
1384
        $this->name_alias   = trim((string) $this->name_alias);
1385
        $this->ref_ext      = (empty($this->ref_ext) ? '' : trim($this->ref_ext));
1386
        $this->address      = trim((string) $this->address);
1387
        $this->zip          = trim((string) $this->zip);
1388
        $this->town         = trim((string) $this->town);
1389
        $this->state_id     = (is_numeric($this->state_id)) ? (int) trim((string) $this->state_id) : 0;
1390
        $this->country_id   = ($this->country_id > 0) ? $this->country_id : 0;
1391
        $this->phone        = trim((string) $this->phone);
1392
        $this->phone        = preg_replace("/\s/", "", $this->phone);
1393
        $this->phone        = preg_replace("/\./", "", $this->phone);
1394
        $this->phone_mobile     = trim((string) $this->phone_mobile);
1395
        $this->phone_mobile     = preg_replace("/\s/", "", $this->phone_mobile);
1396
        $this->phone_mobile     = preg_replace("/\./", "", $this->phone_mobile);
1397
        $this->fax          = trim((string) $this->fax);
1398
        $this->fax          = preg_replace("/\s/", "", $this->fax);
1399
        $this->fax          = preg_replace("/\./", "", $this->fax);
1400
        $this->email        = trim((string) $this->email);
1401
        $this->url          = $this->url ? clean_url($this->url, 0) : '';
1402
        $this->note_private = (empty($this->note_private) ? '' : trim($this->note_private));
1403
        $this->note_public  = (empty($this->note_public) ? '' : trim($this->note_public));
1404
        $this->idprof1      = trim((string) $this->idprof1);
1405
        $this->idprof2      = trim((string) $this->idprof2);
1406
        $this->idprof3      = trim((string) $this->idprof3);
1407
        $this->idprof4      = trim((string) $this->idprof4);
1408
        $this->idprof5      = (!empty($this->idprof5) ? trim($this->idprof5) : '');
1409
        $this->idprof6      = (!empty($this->idprof6) ? trim($this->idprof6) : '');
1410
        $this->prefix_comm  = trim((string) $this->prefix_comm);
1411
        $this->outstanding_limit = price2num($this->outstanding_limit);
1412
        $this->order_min_amount = price2num($this->order_min_amount);
1413
        $this->supplier_order_min_amount = price2num($this->supplier_order_min_amount);
1414
1415
        $this->tva_assuj            = (is_numeric($this->tva_assuj)) ? (int) trim((string) $this->tva_assuj) : 0;
1416
        $this->tva_intra            = dol_sanitizeFileName($this->tva_intra, '');
1417
        $this->vat_reverse_charge   = empty($this->vat_reverse_charge) ? 0 : 1;
1418
        if (empty($this->status)) {
1419
            $this->status = 0;
1420
        }
1421
1422
        if (!empty($this->multicurrency_code)) {
1423
            $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code);
1424
        }
1425
        if (empty($this->fk_multicurrency)) {
1426
            $this->multicurrency_code = '';
1427
            $this->fk_multicurrency = 0;
1428
        }
1429
1430
        // Local taxes
1431
        $this->localtax1_assuj = trim($this->localtax1_assuj);
1432
        $this->localtax2_assuj = trim($this->localtax2_assuj);
1433
1434
        $this->localtax1_value = trim($this->localtax1_value);
1435
        $this->localtax2_value = trim($this->localtax2_value);
1436
1437
        $this->capital = ($this->capital != '') ? (float) price2num(trim((string) $this->capital)) : null;
1438
1439
        $this->effectif_id = trim((string) $this->effectif_id);
1440
        $this->forme_juridique_code = trim((string) $this->forme_juridique_code);
1441
1442
        //Gencod
1443
        $this->barcode = trim($this->barcode);
1444
1445
        // For automatic creation
1446
        if ($this->code_client == -1 || $this->code_client === 'auto') {
1447
            $this->get_codeclient($this, 0);
1448
        }
1449
        if ($this->code_fournisseur == '-1' || $this->code_fournisseur === 'auto') {
1450
            $this->get_codefournisseur($this, 1);
1451
        }
1452
1453
        $this->code_compta_client = trim(empty($this->code_compta) ? $this->code_compta_client : $this->code_compta);
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Cl...s\Societe::$code_compta has been deprecated: Use $code_compta_client ( Ignorable by Annotation )

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

1453
        $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...
1454
        $this->code_compta = $this->code_compta_client; // for backward compatibility
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Cl...s\Societe::$code_compta has been deprecated: Use $code_compta_client ( Ignorable by Annotation )

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

1454
        /** @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...
1455
        $this->code_compta_fournisseur = (empty($this->code_compta_fournisseur) ? '' : trim($this->code_compta_fournisseur));
1456
1457
        // Check parameters. More tests are done later in the ->verify()
1458
        if (!is_numeric($this->client) && !is_numeric($this->fournisseur)) {
1459
            $langs->load("errors");
1460
            $this->error = $langs->trans("BadValueForParameterClientOrSupplier");
1461
            return -1;
1462
        }
1463
1464
        $customer = false;
1465
        if (!empty($allowmodcodeclient) && !empty($this->client)) {
1466
            // If $allowmodcodeclient is set and value is not set, we generate it
1467
            if (empty($this->code_compta_client)) {
1468
                $ret = $this->get_codecompta('customer');
1469
                if ($ret < 0) {
1470
                    return -1;
1471
                }
1472
            }
1473
1474
            $customer = true;
1475
        }
1476
1477
        $supplier = false;
1478
        if (!empty($allowmodcodefournisseur) && !empty($this->fournisseur)) {
1479
            // If $allowmodcodefournisseur is set and value is not set, we generate it
1480
            if (empty($this->code_compta_fournisseur)) {
1481
                $ret = $this->get_codecompta('supplier');
1482
                if ($ret < 0) {
1483
                    return -1;
1484
                }
1485
            }
1486
1487
            $supplier = true;
1488
        }
1489
1490
        //Web services
1491
        $this->webservices_url = $this->webservices_url ? clean_url($this->webservices_url, 0) : '';
1492
        $this->webservices_key = trim($this->webservices_key);
1493
1494
        $this->accountancy_code_buy = (empty($this->accountancy_code_buy) ? '' : trim($this->accountancy_code_buy));
1495
        $this->accountancy_code_sell = (empty($this->accountancy_code_sell) ? '' : trim($this->accountancy_code_sell));
1496
1497
        //Incoterms
1498
        $this->fk_incoterms = (int) $this->fk_incoterms;
1499
        $this->location_incoterms = trim($this->location_incoterms);
1500
1501
        $this->db->begin();
1502
1503
        // Check name is required and codes are ok or unique.
1504
        // If error, this->errors[] is filled
1505
        $result = 0;
1506
        if ($action != 'add' && $action != 'merge') {
1507
            // We don't check when update called during a create because verify was already done.
1508
            // 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
1509
            $result = $this->verify();
1510
1511
            // If there is only one error and error is ErrorBadCustomerCodeSyntax and we don't change customer code, we allow the update
1512
            // So we can update record that were using and old numbering rule.
1513
            if (is_array($this->errors)) {
1514
                if (in_array('ErrorBadCustomerCodeSyntax', $this->errors) && is_object($this->oldcopy) && $this->oldcopy->code_client == $this->code_client) {
1515
                    if (($key = array_search('ErrorBadCustomerCodeSyntax', $this->errors)) !== false) {
1516
                        unset($this->errors[$key]); // Remove error message
1517
                    }
1518
                }
1519
                if (in_array('ErrorBadSupplierCodeSyntax', $this->errors) && is_object($this->oldcopy) && $this->oldcopy->code_fournisseur == $this->code_fournisseur) {
1520
                    if (($key = array_search('ErrorBadSupplierCodeSyntax', $this->errors)) !== false) {
1521
                        unset($this->errors[$key]); // Remove error message
1522
                    }
1523
                }
1524
                if (empty($this->errors)) { // If there is no more error, we can make like if there is no error at all
1525
                    $result = 0;
1526
                }
1527
            }
1528
        }
1529
        $this->setUpperOrLowerCase();
1530
        if ($result >= 0) {
1531
            dol_syslog(get_class($this) . "::update verify ok or not done");
1532
1533
            $sql  = "UPDATE " . MAIN_DB_PREFIX . "societe SET ";
1534
            $sql .= "entity = " . $this->db->escape($this->entity);
1535
            $sql .= ",nom = '" . $this->db->escape($this->name) . "'"; // Required
1536
            $sql .= ",name_alias = '" . $this->db->escape($this->name_alias) . "'";
1537
            $sql .= ",ref_ext = " . (!empty($this->ref_ext) ? "'" . $this->db->escape($this->ref_ext) . "'" : "null");
1538
            $sql .= ",address = '" . $this->db->escape($this->address) . "'";
1539
1540
            $sql .= ",zip = " . (!empty($this->zip) ? "'" . $this->db->escape($this->zip) . "'" : "null");
1541
            $sql .= ",town = " . (!empty($this->town) ? "'" . $this->db->escape($this->town) . "'" : "null");
1542
1543
            $sql .= ",fk_departement = " . ((!empty($this->state_id) && $this->state_id > 0) ? ((int) $this->state_id) : 'null');
1544
            $sql .= ",fk_pays = " . ((!empty($this->country_id) && $this->country_id > 0) ? ((int) $this->country_id) : 'null');
1545
1546
            $sql .= ",phone = " . (!empty($this->phone) ? "'" . $this->db->escape($this->phone) . "'" : "null");
1547
            $sql .= ",phone_mobile = " . (!empty($this->phone_mobile) ? "'" . $this->db->escape($this->phone_mobile) . "'" : "null");
1548
            $sql .= ",fax = " . (!empty($this->fax) ? "'" . $this->db->escape($this->fax) . "'" : "null");
1549
            $sql .= ",email = " . (!empty($this->email) ? "'" . $this->db->escape($this->email) . "'" : "null");
1550
            $sql .= ",socialnetworks = '" . $this->db->escape(json_encode($this->socialnetworks)) . "'";
1551
            $sql .= ",url = " . (!empty($this->url) ? "'" . $this->db->escape($this->url) . "'" : "null");
1552
1553
            $sql .= ",parent = " . ($this->parent > 0 ? $this->parent : "null");
1554
1555
            $sql .= ",note_private = " . (!empty($this->note_private) ? "'" . $this->db->escape($this->note_private) . "'" : "null");
1556
            $sql .= ",note_public = " . (!empty($this->note_public) ? "'" . $this->db->escape($this->note_public) . "'" : "null");
1557
1558
            $sql .= ",siren   = '" . $this->db->escape($this->idprof1) . "'";
1559
            $sql .= ",siret   = '" . $this->db->escape($this->idprof2) . "'";
1560
            $sql .= ",ape     = '" . $this->db->escape($this->idprof3) . "'";
1561
            $sql .= ",idprof4 = '" . $this->db->escape($this->idprof4) . "'";
1562
            $sql .= ",idprof5 = '" . $this->db->escape($this->idprof5) . "'";
1563
            $sql .= ",idprof6 = '" . $this->db->escape($this->idprof6) . "'";
1564
1565
            $sql .= ",tva_assuj = " . ($this->tva_assuj != '' ? "'" . $this->db->escape($this->tva_assuj) . "'" : "null");
1566
            $sql .= ",tva_intra = '" . $this->db->escape($this->tva_intra) . "'";
1567
            if (!getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
1568
                $sql .= ",vat_reverse_charge = " . ($this->vat_reverse_charge != '' ? "'" . $this->db->escape($this->vat_reverse_charge) . "'" : 0);
1569
            }
1570
            $sql .= ",status = " . ((int) $this->status);
1571
1572
            // Local taxes
1573
            $sql .= ",localtax1_assuj = " . ($this->localtax1_assuj != '' ? "'" . $this->db->escape($this->localtax1_assuj) . "'" : "null");
1574
            $sql .= ",localtax2_assuj = " . ($this->localtax2_assuj != '' ? "'" . $this->db->escape($this->localtax2_assuj) . "'" : "null");
1575
            if ($this->localtax1_assuj == 1) {
1576
                if ($this->localtax1_value != '') {
1577
                    $sql .= ",localtax1_value =" . $this->localtax1_value;
1578
                } else {
1579
                    $sql .= ",localtax1_value =0.000";
1580
                }
1581
            } else {
1582
                $sql .= ",localtax1_value =0.000";
1583
            }
1584
1585
            if ($this->localtax2_assuj == 1) {
1586
                if ($this->localtax2_value != '') {
1587
                    $sql .= ",localtax2_value =" . $this->localtax2_value;
1588
                } else {
1589
                    $sql .= ",localtax2_value =0.000";
1590
                }
1591
            } else {
1592
                $sql .= ",localtax2_value =0.000";
1593
            }
1594
1595
            $sql .= ",capital = " . ($this->capital === null ? "null" : $this->capital);
1596
1597
            $sql .= ",prefix_comm = " . (!empty($this->prefix_comm) ? "'" . $this->db->escape($this->prefix_comm) . "'" : "null");
1598
1599
            $sql .= ",fk_effectif = " . ($this->effectif_id > 0 ? ((int) $this->effectif_id) : "null");
1600
            if (isset($this->stcomm_id)) {
1601
                $sql .= ",fk_stcomm=" . (int) $this->stcomm_id;
1602
            }
1603
            if (isset($this->typent_id)) {
1604
                $sql .= ",fk_typent = " . ($this->typent_id > 0 ? ((int) $this->typent_id) : "0");
1605
            }
1606
1607
            $sql .= ",fk_forme_juridique = " . (!empty($this->forme_juridique_code) ? "'" . $this->db->escape($this->forme_juridique_code) . "'" : "null");
1608
1609
            $sql .= ",mode_reglement = " . (!empty($this->mode_reglement_id) ? "'" . $this->db->escape($this->mode_reglement_id) . "'" : "null");
1610
            $sql .= ",cond_reglement = " . (!empty($this->cond_reglement_id) ? "'" . $this->db->escape($this->cond_reglement_id) . "'" : "null");
1611
            $sql .= ",deposit_percent = " . (!empty($this->deposit_percent) ? "'" . $this->db->escape($this->deposit_percent) . "'" : "null");
1612
            $sql .= ",transport_mode = " . (!empty($this->transport_mode_id) ? "'" . $this->db->escape($this->transport_mode_id) . "'" : "null");
1613
            $sql .= ",mode_reglement_supplier = " . (!empty($this->mode_reglement_supplier_id) ? "'" . $this->db->escape($this->mode_reglement_supplier_id) . "'" : "null");
1614
            $sql .= ",cond_reglement_supplier = " . (!empty($this->cond_reglement_supplier_id) ? "'" . $this->db->escape($this->cond_reglement_supplier_id) . "'" : "null");
1615
            $sql .= ",transport_mode_supplier = " . (!empty($this->transport_mode_supplier_id) ? "'" . $this->db->escape($this->transport_mode_supplier_id) . "'" : "null");
1616
            $sql .= ",fk_shipping_method = " . (!empty($this->shipping_method_id) ? "'" . $this->db->escape($this->shipping_method_id) . "'" : "null");
1617
1618
            $sql .= ",client = " . (!empty($this->client) ? $this->client : 0);
1619
            $sql .= ",fournisseur = " . (!empty($this->fournisseur) ? $this->fournisseur : 0);
1620
            $sql .= ",barcode = " . (!empty($this->barcode) ? "'" . $this->db->escape($this->barcode) . "'" : "null");
1621
            $sql .= ",default_lang = " . (!empty($this->default_lang) ? "'" . $this->db->escape($this->default_lang) . "'" : "null");
1622
            $sql .= ",logo = " . (!empty($this->logo) ? "'" . $this->db->escape($this->logo) . "'" : "null");
1623
            $sql .= ",logo_squarred = " . (!empty($this->logo_squarred) ? "'" . $this->db->escape($this->logo_squarred) . "'" : "null");
1624
            $sql .= ",outstanding_limit= " . ($this->outstanding_limit != '' ? $this->outstanding_limit : 'null');
1625
            $sql .= ",order_min_amount= " . ($this->order_min_amount != '' ? $this->order_min_amount : 'null');
1626
            $sql .= ",supplier_order_min_amount= " . ($this->supplier_order_min_amount != '' ? $this->supplier_order_min_amount : 'null');
1627
            $sql .= ",fk_prospectlevel='" . $this->db->escape($this->fk_prospectlevel) . "'";
1628
            if (!getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
1629
                $sql .= ", accountancy_code_buy = '" . $this->db->escape($this->accountancy_code_buy) . "'";
1630
                $sql .= ", accountancy_code_sell= '" . $this->db->escape($this->accountancy_code_sell) . "'";
1631
                if ($customer) {
1632
                    $sql .= ", code_compta = " . (!empty($this->code_compta_client) ? "'" . $this->db->escape($this->code_compta_client) . "'" : "null");
1633
                }
1634
1635
                if ($supplier) {
1636
                    $sql .= ", code_compta_fournisseur = " . (($this->code_compta_fournisseur != "") ? "'" . $this->db->escape($this->code_compta_fournisseur) . "'" : "null");
1637
                }
1638
            }
1639
            $sql .= ",webservices_url = " . (!empty($this->webservices_url) ? "'" . $this->db->escape($this->webservices_url) . "'" : "null");
1640
            $sql .= ",webservices_key = " . (!empty($this->webservices_key) ? "'" . $this->db->escape($this->webservices_key) . "'" : "null");
1641
1642
            //Incoterms
1643
            $sql .= ", fk_incoterms = " . ((int) $this->fk_incoterms);
1644
            $sql .= ", location_incoterms = " . (!empty($this->location_incoterms) ? "'" . $this->db->escape($this->location_incoterms) . "'" : "null");
1645
1646
            if ($customer) {
1647
                $sql .= ", code_client = " . (!empty($this->code_client) ? "'" . $this->db->escape($this->code_client) . "'" : "null");
1648
            }
1649
1650
            if ($supplier) {
1651
                $sql .= ", code_fournisseur = " . (!empty($this->code_fournisseur) ? "'" . $this->db->escape($this->code_fournisseur) . "'" : "null");
1652
            }
1653
            $sql .= ", fk_user_modif = " . ($user->id > 0 ? $user->id : "null");
1654
            $sql .= ", fk_multicurrency = " . (int) $this->fk_multicurrency;
1655
            $sql .= ", multicurrency_code = '" . $this->db->escape($this->multicurrency_code) . "'";
1656
            $sql .= ", model_pdf = '" . $this->db->escape($this->model_pdf) . "'";
1657
            $sql .= " WHERE rowid = " . (int) $id;
1658
1659
            $resql = $this->db->query($sql);
1660
            if ($resql) {
1661
                if (is_object($this->oldcopy)) {    // If we have information on old values
1662
                    if ($this->oldcopy->country_id != $this->country_id) {
1663
                        unset($this->country_code);
1664
                        unset($this->country);
1665
                    }
1666
                    if ($this->oldcopy->state_id != $this->state_id) {
1667
                        unset($this->state_code);
1668
                        unset($this->state);
1669
                    }
1670
                } else {
1671
                    unset($this->country_code); // We clean this, in the doubt, because it may have been changed after an update of country_id
1672
                    unset($this->country);
1673
                    unset($this->state_code);
1674
                    unset($this->state);
1675
                }
1676
1677
                $nbrowsaffected = $this->db->affected_rows($resql);
1678
1679
                if (!$error && $nbrowsaffected) {
1680
                    // Update information on linked member if it is an update
1681
                    if (!$nosyncmember && isModEnabled('member')) {
1682
                        dol_syslog(get_class($this) . "::update update linked member");
1683
1684
                        $lmember = new Adherent($this->db);
1685
                        $result = $lmember->fetch(0, 0, $this->id);
1686
1687
                        if ($result > 0) {
1688
                            $lmember->company = $this->name;
1689
                            //$lmember->firstname=$this->firstname?$this->firstname:$lmember->firstname;    // We keep firstname and lastname of member unchanged
1690
                            //$lmember->lastname=$this->lastname?$this->lastname:$lmember->lastname;        // We keep firstname and lastname of member unchanged
1691
                            $lmember->address = $this->address;
1692
                            $lmember->zip = $this->zip;
1693
                            $lmember->town = $this->town;
1694
                            $lmember->email = $this->email;
1695
                            $lmember->socialnetworks = $this->socialnetworks;
1696
                            $lmember->phone = $this->phone;
1697
                            $lmember->state_id = $this->state_id;
1698
                            $lmember->country_id = $this->country_id;
1699
                            $lmember->default_lang = $this->default_lang;
1700
1701
                            $result = $lmember->update($user, 0, 1, 1, 1); // Use nosync to 1 to avoid cyclic updates
1702
                            if ($result < 0) {
1703
                                $this->error = $lmember->error;
1704
                                $this->errors = array_merge($this->errors, $lmember->errors);
1705
                                dol_syslog(get_class($this) . "::update " . $this->error, LOG_ERR);
1706
                                $error++;
1707
                            }
1708
                        } elseif ($result < 0) {
1709
                            $this->error = $lmember->error;
1710
                            $error++;
1711
                        }
1712
                    }
1713
                }
1714
1715
                $action = 'update';
1716
1717
                // update accountancy for this entity
1718
                if (!$error && getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
1719
                    $this->db->query("DELETE FROM " . MAIN_DB_PREFIX . "societe_perentity WHERE fk_soc = " . ((int) $this->id) . " AND entity = " . ((int) $conf->entity));
1720
1721
                    $sql = "INSERT INTO " . MAIN_DB_PREFIX . "societe_perentity (";
1722
                    $sql .= " fk_soc";
1723
                    $sql .= ", entity";
1724
                    $sql .= ", vat_reverse_charge";
1725
                    $sql .= ", accountancy_code_customer";
1726
                    $sql .= ", accountancy_code_supplier";
1727
                    $sql .= ", accountancy_code_buy";
1728
                    $sql .= ", accountancy_code_sell";
1729
                    $sql .= ") VALUES (";
1730
                    $sql .= $this->id;
1731
                    $sql .= ", " . $conf->entity;
1732
                    $sql .= ", " . (empty($this->vat_reverse_charge) ? '0' : '1');
1733
                    $sql .= ", '" . $this->db->escape($this->code_compta_client) . "'";
1734
                    $sql .= ", '" . $this->db->escape($this->code_compta_fournisseur) . "'";
1735
                    $sql .= ", '" . $this->db->escape($this->accountancy_code_buy) . "'";
1736
                    $sql .= ", '" . $this->db->escape($this->accountancy_code_sell) . "'";
1737
                    $sql .= ")";
1738
                    $result = $this->db->query($sql);
1739
                    if (!$result) {
1740
                        $error++;
1741
                        $this->error = 'ErrorFailedToUpdateAccountancyForEntity';
1742
                    }
1743
                }
1744
1745
                // Actions on extra fields
1746
                if (!$error) {
1747
                    $result = $this->insertExtraFields();
1748
                    if ($result < 0) {
1749
                        $error++;
1750
                    }
1751
                }
1752
                // Actions on extra languages
1753
                if (!$error && !getDolGlobalString('MAIN_EXTRALANGUAGES_DISABLED')) { // For avoid conflicts if trigger used
1754
                    $result = $this->insertExtraLanguages();
1755
                    if ($result < 0) {
1756
                        $error++;
1757
                    }
1758
                }
1759
1760
                if (!$error && $call_trigger) {
1761
                    // Call trigger
1762
                    $result = $this->call_trigger('COMPANY_MODIFY', $user);
1763
                    if ($result < 0) {
1764
                        $error++;
1765
                    }
1766
                    // End call triggers
1767
                }
1768
1769
                if (!$error) {
1770
                    dol_syslog(get_class($this) . "::Update success");
1771
                    $this->db->commit();
1772
                    return 1;
1773
                } else {
1774
                    $this->db->rollback();
1775
                    return -1;
1776
                }
1777
            } else {
1778
                if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
1779
                    // Doublon
1780
                    $this->error = $langs->trans("ErrorDuplicateField");
1781
                    $result = -1;
1782
                } else {
1783
                    $this->error = $this->db->lasterror();
1784
                    $result = -2;
1785
                }
1786
                $this->db->rollback();
1787
                return $result;
1788
            }
1789
        } else {
1790
            $this->db->rollback();
1791
            dol_syslog(get_class($this) . "::Update fails verify " . implode(',', $this->errors), LOG_WARNING);
1792
            return -3;
1793
        }
1794
    }
1795
1796
    /**
1797
     *    Load a third party from database into memory
1798
     *
1799
     *    @param    int     $rowid          Id of third party to load
1800
     *    @param    string  $ref            Reference of third party, name (Warning, this can return several records)
1801
     *    @param    string  $ref_ext        External reference of third party (Warning, this information is a free field not provided by Dolibarr)
1802
     *    @param    string  $barcode        Barcode of third party to load
1803
     *    @param    string  $idprof1        Prof id 1 of third party (Warning, this can return several records)
1804
     *    @param    string  $idprof2        Prof id 2 of third party (Warning, this can return several records)
1805
     *    @param    string  $idprof3        Prof id 3 of third party (Warning, this can return several records)
1806
     *    @param    string  $idprof4        Prof id 4 of third party (Warning, this can return several records)
1807
     *    @param    string  $idprof5        Prof id 5 of third party (Warning, this can return several records)
1808
     *    @param    string  $idprof6        Prof id 6 of third party (Warning, this can return several records)
1809
     *    @param    string  $email          Email of third party (Warning, this can return several records)
1810
     *    @param    string  $ref_alias      Name_alias of third party (Warning, this can return several records)
1811
     *    @param    int     $is_client      Only client third party
1812
     *    @param    int     $is_supplier    Only supplier third party
1813
     *    @return   int                     >0 if OK, <0 if KO or if two records found for same ref or idprof, 0 if not found.
1814
     */
1815
    public function fetch($rowid, $ref = '', $ref_ext = '', $barcode = '', $idprof1 = '', $idprof2 = '', $idprof3 = '', $idprof4 = '', $idprof5 = '', $idprof6 = '', $email = '', $ref_alias = '', $is_client = 0, $is_supplier = 0)
1816
    {
1817
        global $langs;
1818
        global $conf;
1819
1820
        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)) {
1821
            return -1;
1822
        }
1823
1824
        $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';
1825
        $sql .= ', s.status, s.fk_warehouse';
1826
        $sql .= ', s.price_level';
1827
        $sql .= ', s.tms as date_modification, s.fk_user_creat, s.fk_user_modif';
1828
        $sql .= ', s.phone, s.phone_mobile, s.fax, s.email';
1829
        $sql .= ', s.socialnetworks';
1830
        $sql .= ', s.url, s.zip, s.town, s.note_private, s.note_public, s.client, s.fournisseur';
1831
        $sql .= ', s.siren as idprof1, s.siret as idprof2, s.ape as idprof3, s.idprof4, s.idprof5, s.idprof6';
1832
        $sql .= ', s.capital, s.tva_intra';
1833
        $sql .= ', s.fk_typent as typent_id';
1834
        $sql .= ', s.fk_effectif as effectif_id';
1835
        $sql .= ', s.fk_forme_juridique as forme_juridique_code';
1836
        $sql .= ', s.webservices_url, s.webservices_key, s.model_pdf, s.last_main_doc';
1837
        if (!getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
1838
            $sql .= ', s.code_compta, s.code_compta_fournisseur, s.accountancy_code_buy, s.accountancy_code_sell';
1839
            $sql .= ', s.vat_reverse_charge as soc_vat_reverse_charge';
1840
        } else {
1841
            $sql .= ', spe.accountancy_code_customer as code_compta, spe.accountancy_code_supplier as code_compta_fournisseur, spe.accountancy_code_buy, spe.accountancy_code_sell';
1842
            $sql .= ', spe.vat_reverse_charge as spe_vat_reverse_charge';
1843
        }
1844
        $sql .= ', s.code_client, s.code_fournisseur, s.parent, s.barcode';
1845
        $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';
1846
        $sql .= ', s.fk_account, s.tva_assuj';
1847
        $sql .= ', s.mode_reglement_supplier, s.cond_reglement_supplier, s.transport_mode_supplier';
1848
        $sql .= ', s.localtax1_assuj, s.localtax1_value, s.localtax2_assuj, s.localtax2_value, s.fk_prospectlevel, s.default_lang, s.logo, s.logo_squarred';
1849
        $sql .= ', s.fk_shipping_method';
1850
        $sql .= ', s.outstanding_limit, s.import_key, s.canvas, s.fk_incoterms, s.location_incoterms';
1851
        $sql .= ', s.order_min_amount, s.supplier_order_min_amount';
1852
        $sql .= ', s.fk_multicurrency, s.multicurrency_code';
1853
        $sql .= ', fj.libelle as forme_juridique';
1854
        $sql .= ', e.libelle as effectif';
1855
        $sql .= ', c.code as country_code, c.label as country';
1856
        $sql .= ', d.code_departement as state_code, d.nom as state';
1857
        $sql .= ', r.rowid as region_id, r.code_region as region_code';
1858
        $sql .= ', st.libelle as stcomm, st.picto as stcomm_picto';
1859
        $sql .= ', te.code as typent_code';
1860
        $sql .= ', i.libelle as label_incoterms';
1861
        if (!isModEnabled('multicompany')) {
1862
            $sql .= ', s.remise_client, s.remise_supplier';
1863
        } else {
1864
            $sql .= ', sr.remise_client, sr2.remise_supplier';
1865
        }
1866
        $sql .= ' FROM ' . MAIN_DB_PREFIX . 'societe as s';
1867
        if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
1868
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_perentity as spe ON spe.fk_soc = s.rowid AND spe.entity = " . ((int) $conf->entity);
1869
        }
1870
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_effectif as e ON s.fk_effectif = e.id';
1871
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_country as c ON s.fk_pays = c.rowid';
1872
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_stcomm as st ON s.fk_stcomm = st.id';
1873
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_forme_juridique as fj ON s.fk_forme_juridique = fj.code';
1874
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_departements as d ON s.fk_departement = d.rowid';
1875
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_regions as r ON d.fk_region = r.code_region ';
1876
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_typent as te ON s.fk_typent = te.id';
1877
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_incoterms as i ON s.fk_incoterms = i.rowid';
1878
        // With default setup, llx_societe_remise is a history table in default setup and current value is in llx_societe.
1879
        // We use it for real value when multicompany is on. A better place would be into llx_societe_perentity.
1880
        if (isModEnabled('multicompany')) {
1881
            $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') . '))';
1882
            $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') . '))';
1883
        }
1884
        $sql .= ' WHERE s.entity IN (' . getEntity($this->element) . ')';
1885
1886
        // Filter on client or supplier, for Client::fetch() and Fournisseur::fetch()
1887
        if ($is_client) {
1888
            $sql .= ' AND s.client > 0';
1889
        }
1890
        if ($is_supplier) {
1891
            $sql .= ' AND s.fournisseur > 0';
1892
        } // if both false, no test (the thirdparty can be client and/or supplier)
1893
1894
        if ($rowid) {
1895
            $sql .= ' AND s.rowid = ' . ((int) $rowid);
1896
        }
1897
        if ($ref) {
1898
            $sql .= " AND s.nom = '" . $this->db->escape($ref) . "'";
1899
        }
1900
        if ($ref_alias) {
1901
            $sql .= " AND s.name_alias = '" . $this->db->escape($ref_alias) . "'";
1902
        }
1903
        if ($ref_ext) {
1904
            $sql .= " AND s.ref_ext = '" . $this->db->escape($ref_ext) . "'";
1905
        }
1906
        if ($barcode) {
1907
            $sql .= " AND s.barcode = '" . $this->db->escape($barcode) . "'";
1908
        }
1909
        if ($idprof1) {
1910
            $sql .= " AND s.siren = '" . $this->db->escape($idprof1) . "'";
1911
        }
1912
        if ($idprof2) {
1913
            $sql .= " AND s.siret = '" . $this->db->escape($idprof2) . "'";
1914
        }
1915
        if ($idprof3) {
1916
            $sql .= " AND s.ape = '" . $this->db->escape($idprof3) . "'";
1917
        }
1918
        if ($idprof4) {
1919
            $sql .= " AND s.idprof4 = '" . $this->db->escape($idprof4) . "'";
1920
        }
1921
        if ($idprof5) {
1922
            $sql .= " AND s.idprof5 = '" . $this->db->escape($idprof5) . "'";
1923
        }
1924
        if ($idprof6) {
1925
            $sql .= " AND s.idprof6 = '" . $this->db->escape($idprof6) . "'";
1926
        }
1927
        if ($email) {
1928
            $sql .= " AND s.email = '" . $this->db->escape($email) . "'";
1929
        }
1930
1931
        $resql = $this->db->query($sql);
1932
        if ($resql) {
1933
            $num = $this->db->num_rows($resql);
1934
            if ($num > 1) {
1935
                $this->error = 'Fetch found several records. Rename one of thirdparties to avoid duplicate.';
1936
                dol_syslog($this->error, LOG_ERR);
1937
                $result = -2;
1938
            } elseif ($num) {   // $num = 1
1939
                $obj = $this->db->fetch_object($resql);
1940
1941
                $this->id           = $obj->rowid;
1942
                $this->entity       = $obj->entity;
1943
                $this->canvas = $obj->canvas;
1944
1945
                $this->ref          = $obj->rowid;
1946
                $this->name = $obj->name;
1947
                $this->nom          = $obj->name; // deprecated
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

1947
                /** @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...
1948
                $this->name_alias = $obj->name_alias;
1949
                $this->ref_ext      = $obj->ref_ext;
1950
1951
                $this->date_creation     = $this->db->jdate($obj->date_creation);
1952
                $this->date_modification = $this->db->jdate($obj->date_modification);
1953
                $this->user_creation_id     = $obj->fk_user_creat;
1954
                $this->user_modification_id = $obj->fk_user_modif;
1955
1956
                $this->address = $obj->address;
1957
                $this->zip          = $obj->zip;
1958
                $this->town         = $obj->town;
1959
1960
                $this->country_id   = $obj->country_id;
1961
                $this->country_code = $obj->country_id ? $obj->country_code : '';
1962
                $this->country = $obj->country_id ? (($langs->transnoentities('Country' . $obj->country_code) != 'Country' . $obj->country_code) ? $langs->transnoentities('Country' . $obj->country_code) : $obj->country) : '';
1963
1964
                $this->state_id     = $obj->state_id;
1965
                $this->state_code   = $obj->state_code;
1966
                $this->region_id    = $obj->region_id;
1967
                $this->region_code  = $obj->region_code;
1968
                $this->state        = ($obj->state != '-' ? $obj->state : '');
1969
1970
                $transcode = $langs->trans('StatusProspect' . $obj->fk_stcomm);
1971
                $label = ($transcode != 'StatusProspect' . $obj->fk_stcomm ? $transcode : $obj->stcomm);
1972
                $this->stcomm_id = $obj->fk_stcomm; // id status prospect
1973
                $this->status_prospect_label = $label; // label status prospect
1974
                $this->stcomm_picto = $obj->stcomm_picto; // picto statut commercial
1975
1976
                $this->email = $obj->email;
1977
                $this->socialnetworks = ($obj->socialnetworks ? (array) json_decode($obj->socialnetworks, true) : array());
1978
1979
                $this->url = $obj->url;
1980
                $this->phone = $obj->phone;
1981
                $this->phone_mobile = $obj->phone_mobile;
1982
                $this->fax = $obj->fax;
1983
1984
                $this->parent = $obj->parent;
1985
1986
                $this->idprof1      = $obj->idprof1;
1987
                $this->idprof2      = $obj->idprof2;
1988
                $this->idprof3      = $obj->idprof3;
1989
                $this->idprof4      = $obj->idprof4;
1990
                $this->idprof5      = $obj->idprof5;
1991
                $this->idprof6      = $obj->idprof6;
1992
1993
                $this->capital = $obj->capital;
1994
1995
                $this->code_client = $obj->code_client;
1996
                $this->code_fournisseur = $obj->code_fournisseur;
1997
1998
                $this->code_compta = $obj->code_compta;         // For backward compatibility
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Cl...s\Societe::$code_compta has been deprecated: Use $code_compta_client ( Ignorable by Annotation )

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

1998
                /** @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...
1999
                $this->code_compta_client = $obj->code_compta;
2000
                $this->code_compta_fournisseur = $obj->code_compta_fournisseur;
2001
2002
                $this->barcode = $obj->barcode;
2003
2004
                $this->tva_assuj            = $obj->tva_assuj;
2005
                $this->tva_intra            = $obj->tva_intra;
2006
2007
                if (!empty($obj->spe_vat_reverse_charge)) {
2008
                    $this->vat_reverse_charge = $obj->spe_vat_reverse_charge;
2009
                } elseif (!empty($obj->soc_vat_reverse_charge)) {
2010
                    $this->vat_reverse_charge = $obj->soc_vat_reverse_charge;
2011
                } else {
2012
                    $this->vat_reverse_charge = 0;
2013
                }
2014
2015
                $this->status               = $obj->status;
2016
2017
                // Local Taxes
2018
                $this->localtax1_assuj      = $obj->localtax1_assuj;
2019
                $this->localtax2_assuj      = $obj->localtax2_assuj;
2020
2021
                $this->localtax1_value      = $obj->localtax1_value;
2022
                $this->localtax2_value      = $obj->localtax2_value;
2023
2024
                $this->typent_id      = $obj->typent_id;
2025
                $this->typent_code    = $obj->typent_code;
2026
2027
                $this->effectif_id    = $obj->effectif_id;
2028
                $this->effectif       = $obj->effectif_id ? $obj->effectif : '';
2029
2030
                $this->forme_juridique_code = $obj->forme_juridique_code;
2031
                $this->forme_juridique = $obj->forme_juridique_code ? $obj->forme_juridique : '';
2032
2033
                $this->fk_prospectlevel = $obj->fk_prospectlevel;
2034
2035
                $this->prefix_comm = $obj->prefix_comm;
2036
2037
                $this->remise_percent = $obj->remise_client ? price2num($obj->remise_client) : 0; // 0.000000 must be 0
2038
                $this->remise_supplier_percent = $obj->remise_supplier;
2039
2040
                $this->mode_reglement_id    = $obj->mode_reglement;
2041
                $this->cond_reglement_id    = $obj->cond_reglement;
2042
                $this->deposit_percent      = $obj->deposit_percent;
2043
                $this->transport_mode_id    = $obj->transport_mode;
2044
                $this->mode_reglement_supplier_id   = $obj->mode_reglement_supplier;
2045
                $this->cond_reglement_supplier_id   = $obj->cond_reglement_supplier;
2046
                $this->transport_mode_supplier_id = $obj->transport_mode_supplier;
2047
                $this->shipping_method_id = ($obj->fk_shipping_method > 0) ? $obj->fk_shipping_method : null;
2048
                $this->fk_account = $obj->fk_account;
2049
2050
                $this->client = $obj->client;
2051
                $this->fournisseur = $obj->fournisseur;
2052
2053
                $this->note = $obj->note_private; // TODO Deprecated for backward comtability
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$note has been deprecated: Use $note_public, $note_private - Note is split in public and private notes ( Ignorable by Annotation )

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

2053
                /** @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...
2054
                $this->note_private = $obj->note_private;
2055
                $this->note_public = $obj->note_public;
2056
                $this->model_pdf = $obj->model_pdf;
2057
                $this->default_lang = $obj->default_lang;
2058
                $this->logo = $obj->logo;
2059
                $this->logo_squarred = $obj->logo_squarred;
2060
2061
                $this->webservices_url = $obj->webservices_url;
2062
                $this->webservices_key = $obj->webservices_key;
2063
2064
                $this->accountancy_code_buy     = $obj->accountancy_code_buy;
2065
                $this->accountancy_code_sell    = $obj->accountancy_code_sell;
2066
2067
                $this->outstanding_limit        = $obj->outstanding_limit;
2068
                $this->order_min_amount         = $obj->order_min_amount;
2069
                $this->supplier_order_min_amount = $obj->supplier_order_min_amount;
2070
2071
                // multiprix
2072
                $this->price_level = $obj->price_level;
2073
2074
                // warehouse
2075
                $this->fk_warehouse = $obj->fk_warehouse;
2076
2077
                $this->import_key = $obj->import_key;
2078
2079
                //Incoterms
2080
                $this->fk_incoterms = $obj->fk_incoterms;
2081
                $this->location_incoterms = $obj->location_incoterms;
2082
                $this->label_incoterms = $obj->label_incoterms;
2083
2084
                // multicurrency
2085
                $this->fk_multicurrency = $obj->fk_multicurrency;
2086
                $this->multicurrency_code = $obj->multicurrency_code;
2087
2088
                // pdf
2089
                $this->model_pdf = $obj->model_pdf;
2090
                $this->last_main_doc = $obj->last_main_doc;
2091
2092
                $result = 1;
2093
2094
                // fetch optionals attributes and labels
2095
                $this->fetch_optionals();
2096
            } else {
2097
                $result = 0;
2098
            }
2099
2100
            $this->db->free($resql);
2101
        } else {
2102
            $this->error = $this->db->lasterror();
2103
            $this->errors[] = $this->db->lasterror();
2104
            $result = -3;
2105
        }
2106
2107
        // Use first price level if level not defined for third party
2108
        if ((getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES')) && empty($this->price_level)) {
2109
            $this->price_level = 1;
2110
        }
2111
2112
        return $result;
2113
    }
2114
2115
    /**
2116
     *    Delete a third party from database and all its dependencies (contacts, rib...)
2117
     *
2118
     *    @param    int         $id             Id of third party to delete
2119
     *    @param    User|null   $fuser          User who ask to delete thirdparty
2120
     *    @param    int         $call_trigger   0=No, 1=yes
2121
     *    @return   int                         Return integer <0 if KO, 0 if nothing done, >0 if OK
2122
     */
2123
    public function delete($id, User $fuser = null, $call_trigger = 1)
2124
    {
2125
        global $conf, $user;
2126
2127
        if (empty($fuser)) {
2128
            $fuser = $user;
2129
        }
2130
2131
        require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/files.lib.php';
2132
2133
        $entity = isset($this->entity) ? $this->entity : $conf->entity;
2134
2135
        dol_syslog(get_class($this) . "::delete", LOG_DEBUG);
2136
        $error = 0;
2137
2138
        // Test if child exists
2139
        $objectisused = $this->isObjectUsed($id);
2140
        if (empty($objectisused)) {
2141
            $this->db->begin();
2142
2143
            // User is mandatory for trigger call
2144
            if (!$error && $call_trigger) {
2145
                // Call trigger
2146
                $result = $this->call_trigger('COMPANY_DELETE', $fuser);
2147
                if ($result < 0) {
2148
                    $error++;
2149
                }
2150
                // End call triggers
2151
            }
2152
2153
            if (!$error) {
2154
                $static_cat = new Categorie($this->db);
2155
                $toute_categs = array();
2156
2157
                // Fill $toute_categs array with an array of (type => array of ("Categorie" instance))
2158
                $toute_categs['customer'] = $static_cat->containing($this->id, Categorie::TYPE_CUSTOMER);
2159
                $toute_categs['supplier'] = $static_cat->containing($this->id, Categorie::TYPE_SUPPLIER);
2160
2161
                // Remove each "Categorie"
2162
                foreach ($toute_categs as $type => $categs_type) {
2163
                    foreach ($categs_type as $cat) {
2164
                        $cat->del_type($this, $type);
2165
                    }
2166
                }
2167
            }
2168
2169
            if (!$error) {
2170
                foreach ($this->childtablesoncascade as $tabletodelete) {
2171
                    $deleteFromObject = explode(':', $tabletodelete, 4);
2172
                    if (count($deleteFromObject) >= 2) {
2173
                        $className = str_replace('@', '', $deleteFromObject[0]);
2174
                        $filepath = $deleteFromObject[1];
2175
                        $columnName = $deleteFromObject[2];
2176
                        if (dol_include_once($filepath)) {
2177
                            $child_object = new $className($this->db);
2178
                            $result = $child_object->deleteByParentField($id, $columnName);
2179
                            if ($result < 0) {
2180
                                $error++;
2181
                                $this->errors[] = $child_object->error;
2182
                                break;
2183
                            }
2184
                        } else {
2185
                            $error++;
2186
                            $this->errors[] = 'Cannot include child class file ' . $filepath;
2187
                            break;
2188
                        }
2189
                    } else {
2190
                        $sql = "DELETE FROM " . MAIN_DB_PREFIX . $tabletodelete;
2191
                        $sql .= " WHERE fk_soc = " . ((int) $id);
2192
                        if (!$this->db->query($sql)) {
2193
                            $error++;
2194
                            $this->errors[] = $this->db->lasterror();
2195
                            break;
2196
                        }
2197
                    }
2198
                }
2199
            }
2200
2201
            // Removed extrafields
2202
            if (!$error) {
2203
                $result = $this->deleteExtraFields();
2204
                if ($result < 0) {
2205
                    $error++;
2206
                    dol_syslog(get_class($this) . "::delete error -3 " . $this->error, LOG_ERR);
2207
                }
2208
            }
2209
2210
            // Remove links to subsidiaries companies
2211
            if (!$error) {
2212
                $sql = "UPDATE " . MAIN_DB_PREFIX . "societe";
2213
                $sql .= " SET parent = NULL";
2214
                $sql .= " WHERE parent = " . ((int) $id);
2215
                if (!$this->db->query($sql)) {
2216
                    $error++;
2217
                    $this->errors[] = $this->db->lasterror();
2218
                }
2219
            }
2220
2221
            // Remove third party
2222
            if (!$error) {
2223
                if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
2224
                    $sql = "DELETE FROM " . MAIN_DB_PREFIX . "societe_perentity";
2225
                    $sql .= " WHERE fk_soc = " . ((int) $id);
2226
                    if (!$this->db->query($sql)) {
2227
                        $error++;
2228
                        $this->errors[] = $this->db->lasterror();
2229
                    }
2230
                }
2231
2232
                $sql = "DELETE FROM " . MAIN_DB_PREFIX . "societe";
2233
                $sql .= " WHERE rowid = " . ((int) $id);
2234
                if (!$this->db->query($sql)) {
2235
                    $error++;
2236
                    $this->errors[] = $this->db->lasterror();
2237
                }
2238
            }
2239
2240
            if (!$error) {
2241
                $this->db->commit();
2242
2243
                // Delete directory
2244
                if (!empty($conf->societe->multidir_output[$entity])) {
2245
                    $docdir = $conf->societe->multidir_output[$entity] . "/" . $id;
2246
                    if (dol_is_dir($docdir)) {
2247
                        dol_delete_dir_recursive($docdir);
2248
                    }
2249
                }
2250
2251
                return 1;
2252
            } else {
2253
                dol_syslog($this->error, LOG_ERR);
2254
                $this->db->rollback();
2255
                return -1;
2256
            }
2257
        } else {
2258
            dol_syslog("Can't remove thirdparty with id " . $id . ". There are " . $objectisused . " children", LOG_WARNING);
2259
        }
2260
        return 0;
2261
    }
2262
2263
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2264
    /**
2265
     *  Define third party as a customer
2266
     *
2267
     *  @return     int     Return integer <0 if KO, >0 if OK
2268
     *  @deprecated Use setAsCustomer() instead
2269
     *  @see setAsCustomer()
2270
     */
2271
    public function set_as_client()
2272
    {
2273
        global $conf;
2274
		// phpcs:enable
2275
        dol_syslog(get_class($this) . "::set_as_client is deprecated use setAsCustomer instead", LOG_NOTICE);
2276
        return $this->setAsCustomer();
2277
    }
2278
2279
    /**
2280
     *  Define third party as a customer
2281
     *
2282
     *  @return     int     Return integer <0 if KO, >0 if OK
2283
     *  @since dolibarr v19
2284
     */
2285
    public function setAsCustomer()
2286
    {
2287
        if ($this->id) {
2288
            $newclient = 1;
2289
            if (($this->client == 2 || $this->client == 3) && !getDolGlobalInt('SOCIETE_DISABLE_PROSPECTSCUSTOMERS')) {
2290
                $newclient = 3; //If prospect, we keep prospect tag
2291
            }
2292
            $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
2293
            $sql .= " SET client = " . ((int) $newclient);
2294
            $sql .= " WHERE rowid = " . ((int) $this->id);
2295
2296
            $resql = $this->db->query($sql);
2297
            if ($resql) {
2298
                $this->client = $newclient;
2299
                return 1;
2300
            } else {
2301
                return -1;
2302
            }
2303
        }
2304
        return 0;
2305
    }
2306
2307
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2308
    /**
2309
     *  Defines the company as a customer
2310
     *
2311
     *  @param  float   $remise     Value in % of the discount
2312
     *  @param  string  $note       Note/Reason for changing the discount
2313
     *  @param  User    $user       User who sets the discount
2314
     *  @return int                 Return integer <0 if KO, >0 if OK
2315
     */
2316
    public function set_remise_client($remise, $note, User $user)
2317
    {
2318
		// phpcs:enable
2319
        global $conf, $langs;
2320
2321
        // Parameter cleaning
2322
        $note = trim($note);
2323
        if (!$note) {
2324
            $this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("NoteReason"));
2325
            return -2;
2326
        }
2327
2328
        dol_syslog(get_class($this) . "::set_remise_client " . $remise . ", " . $note . ", " . $user->id);
2329
2330
        if ($this->id) {
2331
            $this->db->begin();
2332
2333
            $now = dol_now();
2334
2335
            // Position current discount
2336
            $sql = "UPDATE " . MAIN_DB_PREFIX . "societe ";
2337
            $sql .= " SET remise_client = '" . $this->db->escape($remise) . "'";
2338
            $sql .= " WHERE rowid = " . ((int) $this->id);
2339
            $resql = $this->db->query($sql);
2340
            if (!$resql) {
2341
                $this->db->rollback();
2342
                $this->error = $this->db->error();
2343
                return -1;
2344
            }
2345
2346
            // Writes trace in discount history
2347
            $sql = "INSERT INTO " . MAIN_DB_PREFIX . "societe_remise";
2348
            $sql .= " (entity, datec, fk_soc, remise_client, note, fk_user_author)";
2349
            $sql .= " VALUES (" . $conf->entity . ", '" . $this->db->idate($now) . "', " . ((int) $this->id) . ", '" . $this->db->escape($remise) . "',";
2350
            $sql .= " '" . $this->db->escape($note) . "',";
2351
            $sql .= " " . ((int) $user->id);
2352
            $sql .= ")";
2353
2354
            $resql = $this->db->query($sql);
2355
            if (!$resql) {
2356
                $this->db->rollback();
2357
                $this->error = $this->db->lasterror();
2358
                return -1;
2359
            }
2360
2361
            $this->db->commit();
2362
2363
            return 1;
2364
        }
2365
        return -1;
2366
    }
2367
2368
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2369
    /**
2370
     *  Defines the company as a customer
2371
     *
2372
     *  @param  float   $remise     Value in % of the discount
2373
     *  @param  string  $note       Note/Reason for changing the discount
2374
     *  @param  User    $user       User who sets the discount
2375
     *  @return int                 Return integer <0 if KO, >0 if OK
2376
     */
2377
    public function set_remise_supplier($remise, $note, User $user)
2378
    {
2379
		// phpcs:enable
2380
        global $conf, $langs;
2381
2382
        // Parameter cleaning
2383
        $note = trim($note);
2384
        if (!$note) {
2385
            $this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("NoteReason"));
2386
            return -2;
2387
        }
2388
2389
        dol_syslog(get_class($this) . "::set_remise_supplier " . $remise . ", " . $note . ", " . $user->id);
2390
2391
        if ($this->id) {
2392
            $this->db->begin();
2393
2394
            $now = dol_now();
2395
2396
            // Position current discount
2397
            $sql = "UPDATE " . MAIN_DB_PREFIX . "societe ";
2398
            $sql .= " SET remise_supplier = '" . $this->db->escape($remise) . "'";
2399
            $sql .= " WHERE rowid = " . ((int) $this->id);
2400
            $resql = $this->db->query($sql);
2401
            if (!$resql) {
2402
                $this->db->rollback();
2403
                $this->error = $this->db->error();
2404
                return -1;
2405
            }
2406
2407
            // Writes trace in discount history
2408
            $sql = "INSERT INTO " . MAIN_DB_PREFIX . "societe_remise_supplier";
2409
            $sql .= " (entity, datec, fk_soc, remise_supplier, note, fk_user_author)";
2410
            $sql .= " VALUES (" . $conf->entity . ", '" . $this->db->idate($now) . "', " . ((int) $this->id) . ", '" . $this->db->escape($remise) . "',";
2411
            $sql .= " '" . $this->db->escape($note) . "',";
2412
            $sql .= " " . ((int) $user->id);
2413
            $sql .= ")";
2414
2415
            $resql = $this->db->query($sql);
2416
            if (!$resql) {
2417
                $this->db->rollback();
2418
                $this->error = $this->db->lasterror();
2419
                return -1;
2420
            }
2421
2422
            $this->db->commit();
2423
            return 1;
2424
        }
2425
2426
        return -1;
2427
    }
2428
2429
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2430
    /**
2431
     *      Add a discount for third party
2432
     *
2433
     *      @param  float   $remise             Amount of discount
2434
     *      @param  User    $user               User adding discount
2435
     *      @param  string  $desc               Reason of discount
2436
     *      @param  string  $vatrate            VAT rate (may contain the vat code too). Example: '1.23', '1.23 (ABC)', ...
2437
     *      @param  int     $discount_type      0 => customer discount, 1 => supplier discount
2438
     *      @param  string  $price_base_type    Price base type 'HT' or 'TTC'
2439
     *      @return int                         Return integer <0 if KO, id of discount record if OK
2440
     */
2441
    public function set_remise_except($remise, User $user, $desc, $vatrate = '', $discount_type = 0, $price_base_type = 'HT')
2442
    {
2443
		// phpcs:enable
2444
        global $langs;
2445
2446
        // Clean parameters
2447
        $remise = price2num($remise);
2448
        $desc = trim($desc);
2449
2450
        // Check parameters
2451
        if (!($remise > 0)) {
2452
            $this->error = $langs->trans("ErrorWrongValueForParameter", "1");
2453
            return -1;
2454
        }
2455
        if (!$desc) {
2456
            $this->error = $langs->trans("ErrorWrongValueForParameter", "3");
2457
            return -2;
2458
        }
2459
2460
        if ($this->id > 0) {
2461
            // Clean vat code
2462
            $reg = array();
2463
            $vat_src_code = '';
2464
            if (preg_match('/\((.*)\)/', $vatrate, $reg)) {
2465
                $vat_src_code = $reg[1];
2466
                $vatrate = preg_replace('/\s*\(.*\)/', '', $vatrate); // Remove code into vatrate.
2467
            }
2468
2469
2470
            $discount = new DiscountAbsolute($this->db);
2471
            $discount->fk_soc = $this->id;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Core\Class...scountAbsolute::$fk_soc has been deprecated: Use socid instead. ( Ignorable by Annotation )

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

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

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

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

Loading history...
2472
            $discount->socid = $this->id;
2473
2474
            $discount->discount_type = $discount_type;
2475
2476
            if ($price_base_type == 'TTC') {
2477
                $discount->amount_ttc = $discount->multicurrency_amount_ttc = price2num($remise, 'MT');
2478
                $discount->amount_ht = $discount->multicurrency_amount_ht = price2num((float) $remise / (1 + (float) $vatrate / 100), 'MT');
2479
                $discount->amount_tva = $discount->multicurrency_amount_tva = price2num((float) $discount->amount_ttc - (float) $discount->amount_ht, 'MT');
2480
            } else {
2481
                $discount->amount_ht = $discount->multicurrency_amount_ht = price2num($remise, 'MT');
2482
                $discount->amount_tva = $discount->multicurrency_amount_tva = price2num((float) $remise * (float) $vatrate / 100, 'MT');
2483
                $discount->amount_ttc = $discount->multicurrency_amount_ttc = price2num((float) $discount->amount_ht + (float) $discount->amount_tva, 'MT');
2484
            }
2485
2486
            $discount->tva_tx = (float) price2num($vatrate);
2487
            $discount->vat_src_code = $vat_src_code;
2488
2489
            $discount->description = $desc;
2490
2491
            $result = $discount->create($user);
2492
            if ($result > 0) {
2493
                return $result;
2494
            } else {
2495
                $this->error = $discount->error;
2496
                return -3;
2497
            }
2498
        } else {
2499
            return 0;
2500
        }
2501
    }
2502
2503
    /**
2504
     *  Returns amount of included taxes of the current discounts/credits available from the company
2505
     *
2506
     *  @param  ?User       $user           Filter on a user author of discounts
2507
     *  @param  string      $filter         Other filter
2508
     *  @param  int         $maxvalue       Filter on max value for discount
2509
     *  @param  int<0,1>    $discount_type  0 => customer discount, 1 => supplier discount
2510
     *  @return float|int<-1,-1>        Return integer <0 if KO, Credit note amount otherwise
2511
     */
2512
    public function getAvailableDiscounts($user = null, $filter = '', $maxvalue = 0, $discount_type = 0)
2513
    {
2514
2515
        $discountstatic = new DiscountAbsolute($this->db);
2516
        $result = $discountstatic->getAvailableDiscounts($this, $user, $filter, $maxvalue, $discount_type);
2517
        if ($result >= 0) {
2518
            return $result;
2519
        } else {
2520
            $this->error = $discountstatic->error;
2521
            return -1;
2522
        }
2523
    }
2524
2525
    /**
2526
     *  Return array of sales representatives
2527
     *
2528
     *  @param  User        $user           Object user (not used)
2529
     *  @param  int         $mode           0=Array with properties, 1=Array of IDs.
2530
     *  @param  string      $sortfield      List of sort fields, separated by comma. Example: 't1.fielda,t2.fieldb'
2531
     *  @param  string      $sortorder      Sort order, separated by comma. Example: 'ASC,DESC';
2532
     *  @return array|int                   Array of sales representatives of the current third party or <0 if KO
2533
     */
2534
    public function getSalesRepresentatives(User $user, $mode = 0, $sortfield = null, $sortorder = null)
2535
    {
2536
        global $conf;
2537
2538
        $reparray = array();
2539
2540
        $sql = "SELECT u.rowid, u.login, u.lastname, u.firstname, u.office_phone, u.job, u.email, u.statut as status, u.entity, u.photo, u.gender";
2541
        $sql .= ", u.office_fax, u.user_mobile, u.personal_mobile";
2542
        $sql .= " FROM " . MAIN_DB_PREFIX . "societe_commerciaux as sc, " . MAIN_DB_PREFIX . "user as u";
2543
        // Condition here should be the same than into select_dolusers()
2544
        if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
2545
            $sql .= " WHERE u.rowid IN (SELECT ug.fk_user FROM " . $this->db->prefix() . "usergroup_user as ug WHERE ug.entity IN (" . getEntity('usergroup') . "))";
2546
        } else {
2547
            $sql .= " WHERE entity IN (0, " . $this->db->sanitize($conf->entity) . ")";
2548
        }
2549
2550
        $sql .= " AND u.rowid = sc.fk_user AND sc.fk_soc = " . ((int) $this->id);
2551
        if (empty($sortfield) && empty($sortorder)) {
2552
            $sortfield = 'u.lastname,u.firstname';
2553
            $sortorder = 'ASC,ASC';
2554
        }
2555
        $sql .= $this->db->order($sortfield, $sortorder);
2556
2557
        $resql = $this->db->query($sql);
2558
        if ($resql) {
2559
            $num = $this->db->num_rows($resql);
2560
            $i = 0;
2561
            while ($i < $num) {
2562
                $obj = $this->db->fetch_object($resql);
2563
2564
                if (empty($mode)) {
2565
                    $reparray[$i]['id'] = $obj->rowid;
2566
                    $reparray[$i]['lastname'] = $obj->lastname;
2567
                    $reparray[$i]['firstname'] = $obj->firstname;
2568
                    $reparray[$i]['email'] = $obj->email;
2569
                    $reparray[$i]['phone'] = $obj->office_phone;
2570
                    $reparray[$i]['office_phone'] = $obj->office_phone;         // Pro phone
2571
                    $reparray[$i]['office_fax'] = $obj->office_fax;
2572
                    $reparray[$i]['user_mobile'] = $obj->user_mobile;           // Pro mobile
2573
                    $reparray[$i]['personal_mobile'] = $obj->personal_mobile;   // Personal mobile
2574
                    $reparray[$i]['job'] = $obj->job;
2575
                    $reparray[$i]['statut'] = $obj->status; // deprecated
2576
                    $reparray[$i]['status'] = $obj->status;
2577
                    $reparray[$i]['entity'] = $obj->entity;
2578
                    $reparray[$i]['login'] = $obj->login;
2579
                    $reparray[$i]['photo'] = $obj->photo;
2580
                    $reparray[$i]['gender'] = $obj->gender;
2581
                } else {
2582
                    $reparray[] = $obj->rowid;
2583
                }
2584
                $i++;
2585
            }
2586
            return $reparray;
2587
        } else {
2588
            dol_print_error($this->db);
2589
            return -1;
2590
        }
2591
    }
2592
2593
    /**
2594
     * Set the price level
2595
     *
2596
     * @param   int     $price_level    Level of price
2597
     * @param   User    $user           Use making change
2598
     * @return  int                     Return integer <0 if KO, >0 if OK
2599
     */
2600
    public function setPriceLevel($price_level, User $user)
2601
    {
2602
        if ($this->id) {
2603
            $now = dol_now();
2604
2605
            $sql  = "UPDATE " . MAIN_DB_PREFIX . "societe";
2606
            $sql .= " SET price_level = " . ((int) $price_level);
2607
            $sql .= " WHERE rowid = " . ((int) $this->id);
2608
2609
            if (!$this->db->query($sql)) {
2610
                dol_print_error($this->db);
2611
                return -1;
2612
            }
2613
2614
            $sql  = "INSERT INTO " . MAIN_DB_PREFIX . "societe_prices";
2615
            $sql .= " (datec, fk_soc, price_level, fk_user_author)";
2616
            $sql .= " VALUES ('" . $this->db->idate($now) . "', " . ((int) $this->id) . ", " . ((int) $price_level) . ", " . ((int) $user->id) . ")";
2617
2618
            if (!$this->db->query($sql)) {
2619
                dol_print_error($this->db);
2620
                return -1;
2621
            }
2622
            return 1;
2623
        }
2624
        return -1;
2625
    }
2626
2627
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2628
    /**
2629
     *  Add link to sales representative
2630
     *
2631
     *  @param  User    $user       Object user
2632
     *  @param  int     $commid     Id of user
2633
     *  @return int                 Return integer <=0 if KO, >0 if OK
2634
     */
2635
    public function add_commercial(User $user, $commid)
2636
    {
2637
		// phpcs:enable
2638
        $error = 0;
2639
2640
        if ($this->id > 0 && $commid > 0) {
2641
            $this->db->begin();
2642
2643
            if (!$error) {
2644
                $sql = "DELETE FROM  " . MAIN_DB_PREFIX . "societe_commerciaux";
2645
                $sql .= " WHERE fk_soc = " . ((int) $this->id) . " AND fk_user = " . ((int) $commid);
2646
2647
                $resql = $this->db->query($sql);
2648
                if (!$resql) {
2649
                    dol_syslog(get_class($this) . "::add_commercial Error " . $this->db->lasterror());
2650
                    $error++;
2651
                }
2652
            }
2653
2654
            if (!$error) {
2655
                $sql = "INSERT INTO " . MAIN_DB_PREFIX . "societe_commerciaux";
2656
                $sql .= " (fk_soc, fk_user)";
2657
                $sql .= " VALUES (" . ((int) $this->id) . ", " . ((int) $commid) . ")";
2658
2659
                $resql = $this->db->query($sql);
2660
                if (!$resql) {
2661
                    dol_syslog(get_class($this) . "::add_commercial Error " . $this->db->lasterror());
2662
                    $error++;
2663
                }
2664
            }
2665
2666
            if (!$error) {
2667
                $this->context = array('commercial_modified' => $commid);
2668
2669
                $result = $this->call_trigger('COMPANY_LINK_SALE_REPRESENTATIVE', $user);
2670
                if ($result < 0) {
2671
                    $error++;
2672
                }
2673
            }
2674
2675
            if (!$error) {
2676
                $this->db->commit();
2677
                return 1;
2678
            } else {
2679
                $this->db->rollback();
2680
                return -1;
2681
            }
2682
        }
2683
2684
        return 0;
2685
    }
2686
2687
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2688
    /**
2689
     *  Add link to sales representative
2690
     *
2691
     *  @param  User    $user       Object user
2692
     *  @param  int     $commid     Id of user
2693
     *  @return int                 Return <0 if KO, >0 if OK
2694
     */
2695
    public function del_commercial(User $user, $commid)
2696
    {
2697
		// phpcs:enable
2698
        $error = 0;
2699
        $this->context = array('commercial_modified' => $commid);
2700
2701
        $result = $this->call_trigger('COMPANY_UNLINK_SALE_REPRESENTATIVE', $user);
2702
        if ($result < 0) {
2703
            $error++;
2704
        }
2705
2706
        if ($this->id > 0 && $commid > 0) {
2707
            $sql  = "DELETE FROM  " . MAIN_DB_PREFIX . "societe_commerciaux ";
2708
            $sql .= " WHERE fk_soc = " . ((int) $this->id) . " AND fk_user = " . ((int) $commid);
2709
2710
            if (!$this->db->query($sql)) {
2711
                $error++;
2712
                dol_syslog(get_class($this) . "::del_commercial Erreur");
2713
            }
2714
        }
2715
2716
        if ($error) {
2717
            return -1;
2718
        } else {
2719
            return 1;
2720
        }
2721
    }
2722
2723
    /**
2724
     * getTooltipContentArray
2725
     *
2726
     * @param array $params params to construct tooltip data
2727
     * @since v18
2728
     * @return array
2729
     */
2730
    public function getTooltipContentArray($params)
2731
    {
2732
        global $conf, $langs, $user;
2733
2734
        $langs->loadLangs(['companies', 'commercial']);
2735
2736
        $datas = array();
2737
2738
        $option = $params['option'] ?? '';
2739
        $nofetch = !empty($params['nofetch']);
2740
2741
        $noaliasinname = (empty($params['noaliasinname']) ? 0 : $params['noaliasinname']);
2742
2743
        if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2744
            return ['optimize' => $langs->trans("ShowCompany")];
2745
        }
2746
2747
        if (!empty($this->logo) && class_exists('Form')) {
2748
            $photo = '<div class="photointooltip floatright">';
2749
            $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.
2750
            $photo .= '</div>';
2751
            $datas['photo'] = $photo;
2752
        } elseif (!empty($this->logo_squarred) && class_exists('Form')) {
2753
            /*$label.= '<div class="photointooltip">';
2754
            $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.
2755
            $label.= '</div><div style="clear: both;"></div>';*/
2756
        }
2757
2758
        $datas['divopen'] = '<div class="centpercent">';
2759
2760
        if ($option == 'customer' || $option == 'compta' || $option == 'category') {
2761
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("Customer") . '</u>';
2762
        } elseif ($option == 'prospect' && !getDolGlobalString('SOCIETE_DISABLE_PROSPECTS')) {
2763
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("Prospect") . '</u>';
2764
        } elseif ($option == 'supplier' || $option == 'category_supplier') {
2765
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("Supplier") . '</u>';
2766
        } elseif ($option == 'agenda') {
2767
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("ThirdParty") . '</u>';
2768
        } elseif ($option == 'project') {
2769
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("ThirdParty") . '</u>';
2770
        } elseif ($option == 'margin') {
2771
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("ThirdParty") . '</u>';
2772
        } elseif ($option == 'contact') {
2773
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("ThirdParty") . '</u>';
2774
        } elseif ($option == 'ban') {
2775
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("ThirdParty") . '</u>';
2776
        }
2777
2778
        // By default
2779
        if (empty($datas['picto'])) {
2780
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("ThirdParty") . '</u>';
2781
        }
2782
        if (isset($this->status)) {
2783
            $datas['status'] = ' ' . $this->getLibStatut(5);
2784
        }
2785
        if (isset($this->client) && isset($this->fournisseur)) {
2786
            $datas['type'] = ' &nbsp; ' . $this->getTypeUrl(1);
2787
        }
2788
        $datas['name'] = '<br><b>' . $langs->trans('Name') . ':</b> ' . dol_escape_htmltag(dol_string_nohtmltag($this->name));
2789
        if (!empty($this->name_alias) && empty($noaliasinname)) {
2790
            $datas['namealias'] = ' (' . dol_escape_htmltag(dol_string_nohtmltag($this->name_alias)) . ')';
2791
        }
2792
        if (!empty($this->email)) {
2793
            $datas['email'] = '<br>' . img_picto('', 'email', 'class="pictofixedwidth"') . $this->email;
2794
        }
2795
        if (!empty($this->url)) {
2796
            $datas['url'] = '<br>' . img_picto('', 'globe', 'class="pictofixedwidth"') . $this->url;
2797
        }
2798
        if (!empty($this->phone) || !empty($this->phone_mobile) || !empty($this->fax)) {
2799
            $phonelist = array();
2800
            if ($this->phone) {
2801
                $phonelist[] = dol_print_phone($this->phone, $this->country_code, $this->id, 0, '', '&nbsp', 'phone');
2802
            }
2803
            // deliberately not making new list because fax uses same list as phone
2804
            if ($this->phone_mobile) {
2805
                $phonelist[] = dol_print_phone($this->phone_mobile, $this->country_code, $this->id, 0, '', '&nbsp', 'phone_mobile');
2806
            }
2807
            if ($this->fax) {
2808
                $phonelist[] = dol_print_phone($this->fax, $this->country_code, $this->id, 0, '', '&nbsp', 'fax');
2809
            }
2810
            $datas['phonelist'] = '<br>' . implode('&nbsp;', $phonelist);
2811
        }
2812
2813
        if (!empty($this->address)) {
2814
            $datas['address'] = '<br><b>' . $langs->trans("Address") . ':</b> ' . dol_format_address($this, 1, ' ', $langs); // Address + country
2815
        } elseif (!empty($this->country_code)) {
2816
            $datas['address'] = '<br><b>' . $langs->trans('Country') . ':</b> ' . $this->country_code;
2817
        }
2818
        if (!empty($this->tva_intra) || (getDolGlobalString('SOCIETE_SHOW_FIELD_IN_TOOLTIP') && strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'vatnumber') !== false)) {
2819
            $datas['vatintra'] = '<br><b>' . $langs->trans('VATIntra') . ':</b> ' . dol_escape_htmltag($this->tva_intra);
2820
        }
2821
2822
        if (getDolGlobalString('SOCIETE_SHOW_FIELD_IN_TOOLTIP')) {
2823
            if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid1') !== false && $langs->trans('ProfId1' . $this->country_code) != '-') {
2824
                $datas['profid1'] = '<br><b>' . $langs->trans('ProfId1' . $this->country_code) . ':</b> ' . $this->idprof1;
2825
            }
2826
            if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid2') !== false && $langs->trans('ProfId2' . $this->country_code) != '-') {
2827
                $datas['profid2'] = '<br><b>' . $langs->trans('ProfId2' . $this->country_code) . ':</b> ' . $this->idprof2;
2828
            }
2829
            if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid3') !== false && $langs->trans('ProfId3' . $this->country_code) != '-') {
2830
                $datas['profid3'] = '<br><b>' . $langs->trans('ProfId3' . $this->country_code) . ':</b> ' . $this->idprof3;
2831
            }
2832
            if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid4') !== false && $langs->trans('ProfId4' . $this->country_code) != '-') {
2833
                $datas['profid4'] = '<br><b>' . $langs->trans('ProfId4' . $this->country_code) . ':</b> ' . $this->idprof4;
2834
            }
2835
            if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid5') !== false && $langs->trans('ProfId5' . $this->country_code) != '-') {
2836
                $datas['profid5'] = '<br><b>' . $langs->trans('ProfId5' . $this->country_code) . ':</b> ' . $this->idprof5;
2837
            }
2838
            if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid6') !== false && $langs->trans('ProfId6' . $this->country_code) != '-') {
2839
                $datas['profid6'] = '<br><b>' . $langs->trans('ProfId6' . $this->country_code) . ':</b> ' . $this->idprof6;
2840
            }
2841
        }
2842
2843
        $datas['separator'] = '<br>';
2844
2845
        if (!empty($this->code_client) && ($this->client == 1 || $this->client == 3)) {
2846
            $datas['customercode'] = '<br><b>' . $langs->trans('CustomerCode') . ':</b> ' . $this->code_client;
2847
        }
2848
        if (isModEnabled('accounting') && ($this->client == 1 || $this->client == 3)) {
2849
            $langs->load('compta');
2850
            $datas['accountancycustomercode'] = '<br><b>' . $langs->trans('CustomerAccountancyCode') . ':</b> ' . ($this->code_compta ? $this->code_compta : $this->code_compta_client);
2851
        }
2852
        // show categories for this record only in ajax to not overload lists
2853
        if (!$nofetch && isModEnabled('category') && $this->client) {
2854
            $form = new Form($this->db);
2855
            $datas['categories_customer'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_CUSTOMER, 1, 1);
2856
        }
2857
        if (!empty($this->code_fournisseur) && $this->fournisseur) {
2858
            $datas['suppliercode'] = '<br><b>' . $langs->trans('SupplierCode') . ':</b> ' . $this->code_fournisseur;
2859
        }
2860
        if (isModEnabled('accounting') && $this->fournisseur) {
2861
            $langs->load('compta');
2862
            $datas['accountancysuppliercode'] = '<br><b>' . $langs->trans('SupplierAccountancyCode') . ':</b> ' . $this->code_compta_fournisseur;
2863
        }
2864
        // show categories for this record only in ajax to not overload lists
2865
        if (!$nofetch && isModEnabled('category') && $this->fournisseur) {
2866
            $form = new Form($this->db);
2867
            $datas['categories_supplier'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_SUPPLIER, 1, 1);
2868
        }
2869
2870
        $datas['divclose'] = '</div>';
2871
2872
        return $datas;
2873
    }
2874
2875
    /**
2876
     *      Return a link on thirdparty (with picto)
2877
     *
2878
     *      @param  int     $withpicto                  Add picto into link (0=No picto, 1=Include picto with link, 2=Picto only)
2879
     *      @param  string  $option                     Target of link ('', 'customer', 'prospect', 'supplier', 'project')
2880
     *      @param  int     $maxlen                     Max length of name
2881
     *      @param  int     $notooltip                  1=Disable tooltip
2882
     *      @param  int     $save_lastsearch_value      -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
2883
     *      @param  int     $noaliasinname              1=Do not add alias into the link ref
2884
     *      @param  string  $target                     add attribute target
2885
     *      @param  string  $morecss                    More CSS
2886
     *      @return string                              String with URL
2887
     */
2888
    public function getNomUrl($withpicto = 0, $option = '', $maxlen = 0, $notooltip = 0, $save_lastsearch_value = -1, $noaliasinname = 0, $target = '', $morecss = '')
2889
    {
2890
        global $conf, $langs, $hookmanager, $user;
2891
2892
        if (!empty($conf->dol_no_mouse_hover)) {
2893
            $notooltip = 1; // Force disable tooltips
2894
        }
2895
2896
        $name = $this->name ? $this->name : $this->nom;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

2896
        $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...
2897
2898
        if (getDolGlobalString('SOCIETE_ON_SEARCH_AND_LIST_GO_ON_CUSTOMER_OR_SUPPLIER_CARD')) {
2899
            if (empty($option) && $this->client > 0) {
2900
                $option = 'customer';
2901
            }
2902
            if (empty($option) && $this->fournisseur > 0) {
2903
                $option = 'supplier';
2904
            }
2905
        }
2906
2907
        if (getDolGlobalString('SOCIETE_ADD_REF_IN_LIST') && (!empty($withpicto))) {
2908
            $code = '';
2909
            if (($this->client) && (!empty($this->code_client)) && (getDolGlobalInt('SOCIETE_ADD_REF_IN_LIST') == 1 || getDolGlobalInt('SOCIETE_ADD_REF_IN_LIST') == 2)) {
2910
                $code = $this->code_client . ' - ';
2911
            }
2912
2913
            if (($this->fournisseur) && (!empty($this->code_fournisseur)) && (getDolGlobalInt('SOCIETE_ADD_REF_IN_LIST') == 1 || getDolGlobalInt('SOCIETE_ADD_REF_IN_LIST') == 3)) {
2914
                $code .= $this->code_fournisseur . ' - ';
2915
            }
2916
2917
            if ($code) {
2918
                if (getDolGlobalInt('SOCIETE_ADD_REF_IN_LIST') == 1) {
2919
                    $name = $code . ' ' . $name;
2920
                } else {
2921
                    $name = $code;
2922
                }
2923
            }
2924
        }
2925
2926
        if (!empty($this->name_alias) && empty($noaliasinname)) {
2927
            $name .= ' (' . $this->name_alias . ')';
2928
        }
2929
2930
        $result = '';
2931
        $params = [
2932
            'id' => $this->id,
2933
            'objecttype' => $this->element,
2934
            'option' => $option,
2935
            'nofetch' => 1,
2936
        ];
2937
        $classfortooltip = 'classfortooltip';
2938
        $dataparams = '';
2939
        if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
2940
            $classfortooltip = 'classforajaxtooltip';
2941
            $dataparams = ' data-params="' . dol_escape_htmltag(json_encode($params)) . '"';
2942
            $label = '';
2943
        } else {
2944
            $label = implode($this->getTooltipContentArray($params));
2945
        }
2946
2947
        $linkstart = '';
2948
        $linkend = '';
2949
2950
        if ($option == 'customer' || $option == 'compta' || $option == 'category') {
2951
            $linkstart = '<a href="' . constant('BASE_URL') . '/comm/card.php?socid=' . $this->id;
2952
        } elseif ($option == 'prospect' && !getDolGlobalString('SOCIETE_DISABLE_PROSPECTS')) {
2953
            $linkstart = '<a href="' . constant('BASE_URL') . '/comm/card.php?socid=' . $this->id;
2954
        } elseif ($option == 'supplier' || $option == 'category_supplier') {
2955
            $linkstart = '<a href="' . constant('BASE_URL') . '/fourn/card.php?socid=' . $this->id;
2956
        } elseif ($option == 'agenda') {
2957
            $linkstart = '<a href="' . constant('BASE_URL') . '/societe/agenda.php?socid=' . $this->id;
2958
        } elseif ($option == 'project') {
2959
            $linkstart = '<a href="' . constant('BASE_URL') . '/societe/project.php?socid=' . $this->id;
2960
        } elseif ($option == 'margin') {
2961
            $linkstart = '<a href="' . constant('BASE_URL') . '/margin/tabs/thirdpartyMargins.php?socid=' . $this->id . '&type=1';
2962
        } elseif ($option == 'contact') {
2963
            $linkstart = '<a href="' . constant('BASE_URL') . '/societe/contact.php?socid=' . $this->id;
2964
        } elseif ($option == 'ban') {
2965
            $linkstart = '<a href="' . constant('BASE_URL') . '/societe/paymentmodes.php?socid=' . $this->id;
2966
        }
2967
2968
        // By default
2969
        if (empty($linkstart)) {
2970
            $linkstart = '<a href="' . constant('BASE_URL') . '/societe/card.php?socid=' . $this->id;
2971
        }
2972
2973
        // Add type of canvas
2974
        $linkstart .= (!empty($this->canvas) ? '&canvas=' . $this->canvas : '');
2975
        // Add param to save lastsearch_values or not
2976
        $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
2977
        if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
2978
            $add_save_lastsearch_values = 1;
2979
        }
2980
        if ($add_save_lastsearch_values) {
2981
            $linkstart .= '&save_lastsearch_values=1';
2982
        }
2983
        $linkstart .= '"';
2984
2985
        $linkclose = '';
2986
        if (empty($notooltip)) {
2987
            if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2988
                $label = $langs->trans("ShowCompany");
2989
                $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"';
2990
            }
2991
            $linkclose .= ($label ? ' title="' . dol_escape_htmltag($label, 1) . '"' : ' title="tocomplete"');
2992
            $linkclose .= $dataparams . ' class="' . $classfortooltip . ($morecss ? ' ' . $morecss : '') . ' refurl valignmiddle"';
2993
            $target_value = array('_self', '_blank', '_parent', '_top');
2994
            if (in_array($target, $target_value)) {
2995
                $linkclose .= ' target="' . dol_escape_htmltag($target) . '"';
2996
            }
2997
        } else {
2998
            $linkclose .= ' class="valignmiddle' . ($morecss ? ' ' . $morecss : '') . '"';
2999
        }
3000
        $linkstart .= $linkclose . '>';
3001
        $linkend = '</a>';
3002
3003
        if (!$user->hasRight('societe', 'client', 'voir') && $user->socid > 0 && $this->id != $user->socid) {
3004
            $linkstart = '';
3005
            $linkend = '';
3006
        }
3007
3008
        $result .= $linkstart;
3009
        if ($withpicto) {
3010
            $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), (' class="' . (($withpicto != 2) ? 'paddingright' : '') . '"'), 0, 0, $notooltip ? 0 : 1);
3011
        }
3012
        if ($withpicto != 2) {
3013
            $result .= dol_escape_htmltag($maxlen ? dol_trunc($name, $maxlen) : $name);
3014
        }
3015
        $result .= $linkend;
3016
3017
        global $action;
3018
        $hookmanager->initHooks(array('thirdpartydao'));
3019
        $parameters = array(
3020
            'id' => $this->id,
3021
            'getnomurl' => &$result,
3022
            'withpicto ' => $withpicto,
3023
            'option' => $option,
3024
            'maxlen' => $maxlen,
3025
            'notooltip' => $notooltip,
3026
            'save_lastsearch_value' => $save_lastsearch_value
3027
        );
3028
        $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
3029
        if ($reshook > 0) {
3030
            $result = $hookmanager->resPrint;
3031
        } else {
3032
            $result .= $hookmanager->resPrint;
3033
        }
3034
3035
        return $result;
3036
    }
3037
3038
    /**
3039
     *      Return link(s) on type of thirdparty (with picto)
3040
     *
3041
     *      @param  int     $withpicto              Add picto into link (0=No picto, 1=Include picto with link, 2=Picto only)
3042
     *      @param  string  $option                 ''=All
3043
     *      @param  int     $notooltip              1=Disable tooltip
3044
     *      @param  string  $tag                    Tag 'a' or 'span'
3045
     *      @return string                          String with URL
3046
     */
3047
    public function getTypeUrl($withpicto = 0, $option = '', $notooltip = 0, $tag = 'a')
3048
    {
3049
        global $conf, $langs;
3050
3051
        $s = '';
3052
        if (empty($option) || preg_match('/prospect/', $option)) {
3053
            if (($this->client == 2 || $this->client == 3) && !getDolGlobalString('SOCIETE_DISABLE_PROSPECTS')) {
3054
                $s .= '<' . $tag . ' class="customer-back opacitymedium" title="' . $langs->trans("Prospect") . '" href="' . constant('BASE_URL') . '/comm/card.php?socid=' . $this->id . '">' . dol_substr($langs->trans("Prospect"), 0, 1) . '</' . $tag . '>';
3055
            }
3056
        }
3057
        if (empty($option) || preg_match('/customer/', $option)) {
3058
            if (($this->client == 1 || $this->client == 3) && !getDolGlobalString('SOCIETE_DISABLE_CUSTOMERS')) {
3059
                $s .= '<' . $tag . ' class="customer-back" title="' . $langs->trans("Customer") . '" href="' . constant('BASE_URL') . '/comm/card.php?socid=' . $this->id . '">' . dol_substr($langs->trans("Customer"), 0, 1) . '</' . $tag . '>';
3060
            }
3061
        }
3062
        if (empty($option) || preg_match('/supplier/', $option)) {
3063
            if ((isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) && $this->fournisseur) {
3064
                $s .= '<' . $tag . ' class="vendor-back" title="' . $langs->trans("Supplier") . '" href="' . constant('BASE_URL') . '/fourn/card.php?socid=' . $this->id . '">' . dol_substr($langs->trans("Supplier"), 0, 1) . '</' . $tag . '>';
3065
            }
3066
        }
3067
        return $s;
3068
    }
3069
3070
3071
    /**
3072
     *    Return label of status (activity, closed)
3073
     *
3074
     *    @param    int     $mode       0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
3075
     *    @return   string              Label of status
3076
     */
3077
    public function getLibStatut($mode = 0)
3078
    {
3079
        return $this->LibStatut($this->status, $mode);
3080
    }
3081
3082
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3083
    /**
3084
     *  Return the label of a given status
3085
     *
3086
     *  @param  int     $status         Status id
3087
     *  @param  int     $mode           0=Long label, 1=Short label, 2=Picto + Short label, 3=Picto, 4=Picto + Long label, 5=Short label + Picto, 6=Long label + Picto
3088
     *  @return string                  Status label
3089
     */
3090
    public function LibStatut($status, $mode = 0)
3091
    {
3092
		// phpcs:enable
3093
        global $langs;
3094
        $langs->load('companies');
3095
3096
        $statusType = 'status4';
3097
        if ($status == 0) {
3098
            $statusType = 'status6';
3099
        }
3100
3101
        if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
3102
            $this->labelStatus[0] = $langs->transnoentitiesnoconv("ActivityCeased");
3103
            $this->labelStatus[1] = $langs->transnoentitiesnoconv("InActivity");
3104
            $this->labelStatusShort[0] = $langs->transnoentitiesnoconv("ActivityCeased");
3105
            $this->labelStatusShort[1] = $langs->transnoentitiesnoconv("InActivity");
3106
        }
3107
3108
        return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
3109
    }
3110
3111
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3112
    /**
3113
     *    Return list of contacts emails existing for third party
3114
     *
3115
     *    @param    int     $addthirdparty      1=Add also a record for thirdparty email, 2=Same than 1 but add text ThirdParty in grey
3116
     *    @return   array                       Array of contacts emails
3117
     */
3118
    public function thirdparty_and_contact_email_array($addthirdparty = 0)
3119
    {
3120
		// phpcs:enable
3121
        global $langs;
3122
3123
        $contact_emails = $this->contact_property_array('email', 1);
3124
3125
        if ($this->email && $addthirdparty) {
3126
            if (empty($this->name)) {
3127
                $this->name = $this->nom;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

3127
                $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...
3128
            }
3129
            $contact_emails['thirdparty'] = ($addthirdparty == 2 ? '<span class="opacitymedium">' : '') . $langs->transnoentitiesnoconv("ThirdParty") . ($addthirdparty == 2 ? '</span>' : '') . ': ' . dol_trunc($this->name, 16) . " <" . $this->email . ">";
3130
        }
3131
3132
        //var_dump($contact_emails)
3133
        return $contact_emails;
3134
    }
3135
3136
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3137
    /**
3138
     *    Return list of contacts mobile phone existing for third party
3139
     *
3140
     *    @return     array       Array of contacts emails
3141
     */
3142
    public function thirdparty_and_contact_phone_array()
3143
    {
3144
		// phpcs:enable
3145
        global $langs;
3146
3147
        $contact_phone = $this->contact_property_array('mobile');
3148
3149
        if (!empty($this->phone)) { // If a phone of thirdparty is defined, we add it to mobile of contacts
3150
            if (empty($this->name)) {
3151
                $this->name = $this->nom;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

3151
                $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...
3152
            }
3153
            // TODO: Tester si tel non deja present dans tableau contact
3154
            $contact_phone['thirdparty'] = $langs->transnoentitiesnoconv("ThirdParty") . ': ' . dol_trunc($this->name, 16) . " <" . $this->phone . ">";
3155
        }
3156
        return $contact_phone;
3157
    }
3158
3159
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3160
    /**
3161
     *  Return list of contacts emails or mobile existing for third party
3162
     *
3163
     *  @param  string  $mode               'email' or 'mobile'
3164
     *  @param  int     $hidedisabled       1=Hide contact if disabled
3165
     *  @return array                       Array of contacts emails or mobile. Example: array(id=>'Name <email>')
3166
     */
3167
    public function contact_property_array($mode = 'email', $hidedisabled = 0)
3168
    {
3169
		// phpcs:enable
3170
        global $langs;
3171
3172
        $contact_property = array();
3173
3174
3175
        $sql = "SELECT rowid, email, statut as status, phone_mobile, lastname, poste, firstname";
3176
        $sql .= " FROM " . MAIN_DB_PREFIX . "socpeople";
3177
        $sql .= " WHERE fk_soc = " . ((int) $this->id);
3178
        $sql .= " AND entity IN (" . getEntity($this->element) . ")";
3179
        $sql .= " ORDER BY lastname, firstname";
3180
3181
        $resql = $this->db->query($sql);
3182
        if ($resql) {
3183
            $nump = $this->db->num_rows($resql);
3184
            if ($nump) {
3185
                $sepa = "(";
3186
                $sepb = ")";
3187
                if ($mode == 'email') {
3188
                    //$sepa="&lt;"; $sepb="&gt;";
3189
                    $sepa = "<";
3190
                    $sepb = ">";
3191
                }
3192
                $i = 0;
3193
                while ($i < $nump) {
3194
                    $obj = $this->db->fetch_object($resql);
3195
                    if ($mode == 'email') {
3196
                        $property = $obj->email;
3197
                    } elseif ($mode == 'mobile') {
3198
                        $property = $obj->phone_mobile;
3199
                    } else {
3200
                        $property = $obj->$mode;
3201
                    }
3202
3203
                    // Show all contact. If hidedisabled is 1, showonly contacts with status = 1
3204
                    if ($obj->status == 1 || empty($hidedisabled)) {
3205
                        if (empty($property)) {
3206
                            if ($mode == 'email') {
3207
                                $property = $langs->transnoentitiesnoconv("NoEMail");
3208
                            } elseif ($mode == 'mobile') {
3209
                                $property = $langs->transnoentitiesnoconv("NoMobilePhone");
3210
                            }
3211
                        }
3212
3213
                        if (!empty($obj->poste)) {
3214
                            $contact_property[$obj->rowid] = trim(dolGetFirstLastname($obj->firstname, $obj->lastname)) . ($obj->poste ? " - " . $obj->poste : "") . (($mode != 'poste' && $property) ? " " . $sepa . $property . $sepb : '');
3215
                        } else {
3216
                            $contact_property[$obj->rowid] = trim(dolGetFirstLastname($obj->firstname, $obj->lastname)) . (($mode != 'poste' && $property) ? " " . $sepa . $property . $sepb : '');
3217
                        }
3218
                    }
3219
                    $i++;
3220
                }
3221
            }
3222
        } else {
3223
            dol_print_error($this->db);
3224
        }
3225
        return $contact_property;
3226
    }
3227
3228
3229
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3230
    /**
3231
     *    Returns the contact list of this company
3232
     *
3233
     *    @return     array      array of contacts
3234
     */
3235
    public function contact_array()
3236
    {
3237
		// phpcs:enable
3238
        $contacts = array();
3239
3240
        $sql = "SELECT rowid, lastname, firstname FROM " . MAIN_DB_PREFIX . "socpeople WHERE fk_soc = " . ((int) $this->id);
3241
        $resql = $this->db->query($sql);
3242
        if ($resql) {
3243
            $nump = $this->db->num_rows($resql);
3244
            if ($nump) {
3245
                $i = 0;
3246
                while ($i < $nump) {
3247
                    $obj = $this->db->fetch_object($resql);
3248
                    $contacts[$obj->rowid] = dolGetFirstLastname($obj->firstname, $obj->lastname);
3249
                    $i++;
3250
                }
3251
            }
3252
        } else {
3253
            dol_print_error($this->db);
3254
        }
3255
        return $contacts;
3256
    }
3257
3258
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3259
    /**
3260
     *    Returns the contact list of this company
3261
     *
3262
     *    @return    array    $contacts    array of contacts
3263
     */
3264
    public function contact_array_objects()
3265
    {
3266
        $contacts = array();
3267
3268
        $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "socpeople WHERE fk_soc = " . ((int) $this->id);
3269
        $resql = $this->db->query($sql);
3270
        if ($resql) {
3271
            $nump = $this->db->num_rows($resql);
3272
            if ($nump) {
3273
                $i = 0;
3274
                while ($i < $nump) {
3275
                    $obj = $this->db->fetch_object($resql);
3276
                    $contact = new Contact($this->db);
3277
                    $contact->fetch($obj->rowid);
3278
                    $contacts[] = $contact;
3279
                    $i++;
3280
                }
3281
            }
3282
        } else {
3283
            dol_print_error($this->db);
3284
        }
3285
        return $contacts;
3286
    }
3287
3288
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3289
    /**
3290
     *  Return property of contact from its id
3291
     *
3292
     *  @param  int     $rowid      id of contact
3293
     *  @param  string  $mode       'email' or 'mobile'
3294
     *  @return string              Email of contact with format: "Full name <email>"
3295
     */
3296
    public function contact_get_property($rowid, $mode)
3297
    {
3298
		// phpcs:enable
3299
        $contact_property = '';
3300
3301
        if (empty($rowid)) {
3302
            return '';
3303
        }
3304
3305
        $sql = "SELECT rowid, email, phone_mobile, lastname, firstname";
3306
        $sql .= " FROM " . MAIN_DB_PREFIX . "socpeople";
3307
        $sql .= " WHERE rowid = " . ((int) $rowid);
3308
3309
        $resql = $this->db->query($sql);
3310
        if ($resql) {
3311
            $nump = $this->db->num_rows($resql);
3312
3313
            if ($nump) {
3314
                $obj = $this->db->fetch_object($resql);
3315
3316
                if ($mode == 'email') {
3317
                    $contact_property = dol_string_nospecial(dolGetFirstLastname($obj->firstname, $obj->lastname), ' ', array(",")) . " <" . $obj->email . ">";
3318
                } elseif ($mode == 'mobile') {
3319
                    $contact_property = $obj->phone_mobile;
3320
                }
3321
            }
3322
            return $contact_property;
3323
        } else {
3324
            dol_print_error($this->db);
3325
        }
3326
3327
        return '';
3328
    }
3329
3330
3331
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3332
    /**
3333
     *  Return bank number property of thirdparty (label or rum)
3334
     *
3335
     *  @param  string  $mode   'label' or 'rum' or 'format'
3336
     *  @return string          Bank label or RUM or '' if no bank account found
3337
     */
3338
    public function display_rib($mode = 'label')
3339
    {
3340
		// phpcs:enable
3341
3342
        $bac = new CompanyBankAccount($this->db);
3343
        // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
3344
        $bac->fetch(0, '', $this->id);
3345
3346
        if ($bac->id > 0) {     // If a bank account has been found for company $this->id
3347
            if ($mode == 'label') {
3348
                return $bac->getRibLabel(true);
3349
            } elseif ($mode == 'rum') {
3350
                if (empty($bac->rum)) {
3351
                    $prelevement = new BonPrelevement($this->db);
3352
                    $bac->fetch_thirdparty();
3353
                    $bac->rum = $prelevement->buildRumNumber($bac->thirdparty->code_client, $bac->datec, $bac->id);
3354
                }
3355
                return $bac->rum;
3356
            } elseif ($mode == 'format') {
3357
                return $bac->frstrecur;
3358
            } else {
3359
                return 'BadParameterToFunctionDisplayRib';
3360
            }
3361
        } else {
3362
            return '';
3363
        }
3364
    }
3365
3366
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3367
    /**
3368
     * Return Array of RIB
3369
     *
3370
     * @return    CompanyBankAccount[]|int        Return 0 if KO, Array of CompanyBankAccount if OK
3371
     */
3372
    public function get_all_rib()
3373
    {
3374
		// phpcs:enable
3375
        $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "societe_rib WHERE type='ban' AND fk_soc = " . ((int) $this->id);
3376
        $result = $this->db->query($sql);
3377
        if (!$result) {
3378
            $this->error++;
3379
            $this->errors[] = $this->db->lasterror;
3380
            return 0;
3381
        } else {
3382
            $num_rows = $this->db->num_rows($result);
3383
            $rib_array = array();
3384
            if ($num_rows) {
3385
                while ($obj = $this->db->fetch_object($result)) {
3386
                    $rib = new CompanyBankAccount($this->db);
3387
                    $rib->fetch($obj->rowid);
3388
                    $rib_array[] = $rib;
3389
                }
3390
            }
3391
            return $rib_array;
3392
        }
3393
    }
3394
3395
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3396
    /**
3397
     *  Assigns a customer code from the code control module.
3398
     *  Return value is stored into this->code_client
3399
     *
3400
     *  @param  Societe     $objsoc     Object thirdparty
3401
     *  @param  int         $type       Should be 0 to say customer
3402
     *  @return void
3403
     */
3404
    public function get_codeclient($objsoc = null, $type = 0)
3405
    {
3406
		// phpcs:enable
3407
        global $conf;
3408
        if (getDolGlobalString('SOCIETE_CODECLIENT_ADDON')) {
3409
            $module = getDolGlobalString('SOCIETE_CODECLIENT_ADDON');
3410
3411
            $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
3412
            foreach ($dirsociete as $dirroot) {
3413
                $res = dol_include_once($dirroot . $module . '.php');
3414
                if ($res) {
3415
                    break;
3416
                }
3417
            }
3418
            /** @var ModeleThirdPartyCode $mod */
3419
            $mod = new $module($this->db);
3420
3421
            $this->code_client = $mod->getNextValue($objsoc, $type);
3422
            $this->prefixCustomerIsRequired = $mod->prefixIsRequired;
3423
3424
            dol_syslog(get_class($this) . "::get_codeclient code_client=" . $this->code_client . " module=" . $module);
3425
        }
3426
    }
3427
3428
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3429
    /**
3430
     *  Assigns a vendor code from the code control module.
3431
     *  Return value is stored into this->code_fournisseur
3432
     *
3433
     *  @param  Societe     $objsoc     Object thirdparty
3434
     *  @param  int         $type       Should be 1 to say supplier
3435
     *  @return void
3436
     */
3437
    public function get_codefournisseur($objsoc = null, $type = 1)
3438
    {
3439
		// phpcs:enable
3440
        global $conf;
3441
        if (getDolGlobalString('SOCIETE_CODECLIENT_ADDON')) {
3442
            $module = getDolGlobalString('SOCIETE_CODECLIENT_ADDON');
3443
3444
            $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
3445
            foreach ($dirsociete as $dirroot) {
3446
                $res = dol_include_once($dirroot . $module . '.php');
3447
                if ($res) {
3448
                    break;
3449
                }
3450
            }
3451
            /** @var ModeleThirdPartyCode $mod */
3452
            $mod = new $module($this->db);
3453
3454
            $this->code_fournisseur = $mod->getNextValue($objsoc, $type);
3455
3456
            dol_syslog(get_class($this) . "::get_codefournisseur code_fournisseur=" . $this->code_fournisseur . " module=" . $module);
3457
        }
3458
    }
3459
3460
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3461
    /**
3462
     *    Check if a client code is editable based on the parameters of the
3463
     *    code control module.
3464
     *
3465
     *    @return     int       0=No, 1=Yes
3466
     */
3467
    public function codeclient_modifiable()
3468
    {
3469
		// phpcs:enable
3470
        global $conf;
3471
        if (getDolGlobalString('SOCIETE_CODECLIENT_ADDON')) {
3472
            $module = getDolGlobalString('SOCIETE_CODECLIENT_ADDON');
3473
3474
            $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
3475
            foreach ($dirsociete as $dirroot) {
3476
                $res = dol_include_once($dirroot . $module . '.php');
3477
                if ($res) {
3478
                    break;
3479
                }
3480
            }
3481
3482
            $mod = new $module($this->db);
3483
3484
            dol_syslog(get_class($this) . "::codeclient_modifiable code_client=" . $this->code_client . " module=" . $module);
3485
            if ($mod->code_modifiable_null && !$this->code_client) {
3486
                return 1;
3487
            }
3488
            if ($mod->code_modifiable_invalide && $this->check_codeclient() < 0) {
3489
                return 1;
3490
            }
3491
            if ($mod->code_modifiable) {
3492
                return 1; // A mettre en dernier
3493
            }
3494
            return 0;
3495
        } else {
3496
            return 0;
3497
        }
3498
    }
3499
3500
3501
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3502
    /**
3503
     *    Check if a vendor code is editable in the code control module configuration
3504
     *
3505
     *    @return     int       0=No, 1=Yes
3506
     */
3507
    public function codefournisseur_modifiable()
3508
    {
3509
		// phpcs:enable
3510
        global $conf;
3511
        if (getDolGlobalString('SOCIETE_CODECLIENT_ADDON')) {
3512
            $module = getDolGlobalString('SOCIETE_CODECLIENT_ADDON');
3513
3514
            $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
3515
            foreach ($dirsociete as $dirroot) {
3516
                $res = dol_include_once($dirroot . $module . '.php');
3517
                if ($res) {
3518
                    break;
3519
                }
3520
            }
3521
3522
            $mod = new $module($this->db);
3523
3524
            dol_syslog(get_class($this) . "::codefournisseur_modifiable code_founisseur=" . $this->code_fournisseur . " module=" . $module);
3525
            if ($mod->code_modifiable_null && !$this->code_fournisseur) {
3526
                return 1;
3527
            }
3528
            if ($mod->code_modifiable_invalide && $this->check_codefournisseur() < 0) {
3529
                return 1;
3530
            }
3531
            if ($mod->code_modifiable) {
3532
                return 1; // A mettre en dernier
3533
            }
3534
            return 0;
3535
        } else {
3536
            return 0;
3537
        }
3538
    }
3539
3540
3541
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3542
    /**
3543
     *  Check customer code
3544
     *
3545
     *  @return     int             0 if OK
3546
     *                              -1 ErrorBadCustomerCodeSyntax
3547
     *                              -2 ErrorCustomerCodeRequired
3548
     *                              -3 ErrorCustomerCodeAlreadyUsed
3549
     *                              -4 ErrorPrefixRequired
3550
     *                              -5 NotConfigured - Setup empty so any value may be ok or not
3551
     *                              -6 Other (see this->error)
3552
     */
3553
    public function check_codeclient()
3554
    {
3555
		// phpcs:enable
3556
        global $conf;
3557
        if (getDolGlobalString('SOCIETE_CODECLIENT_ADDON')) {
3558
            $module = getDolGlobalString('SOCIETE_CODECLIENT_ADDON');
3559
3560
            $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
3561
            foreach ($dirsociete as $dirroot) {
3562
                $res = dol_include_once($dirroot . $module . '.php');
3563
                if ($res) {
3564
                    break;
3565
                }
3566
            }
3567
3568
            $mod = new $module($this->db);
3569
3570
            dol_syslog(get_class($this) . "::check_codeclient code_client=" . $this->code_client . " module=" . $module);
3571
            $result = $mod->verif($this->db, $this->code_client, $this, 0);
3572
            if ($result) {  // If error
3573
                $this->error = $mod->error;
3574
                $this->errors = $mod->errors;
3575
            }
3576
            return $result;
3577
        } else {
3578
            return 0;
3579
        }
3580
    }
3581
3582
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3583
    /**
3584
     *    Check supplier code
3585
     *
3586
     *    @return     int       0 if OK
3587
     *                          -1 ErrorBadCustomerCodeSyntax
3588
     *                          -2 ErrorCustomerCodeRequired
3589
     *                          -3 ErrorCustomerCodeAlreadyUsed
3590
     *                          -4 ErrorPrefixRequired
3591
     *                          -5 NotConfigured - Setup empty so any value may be ok or not
3592
     *                          -6 Other (see this->error)
3593
     */
3594
    public function check_codefournisseur()
3595
    {
3596
		// phpcs:enable
3597
        global $conf;
3598
        if (getDolGlobalString('SOCIETE_CODECLIENT_ADDON')) {
3599
            $module = getDolGlobalString('SOCIETE_CODECLIENT_ADDON');
3600
3601
            $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
3602
            foreach ($dirsociete as $dirroot) {
3603
                $res = dol_include_once($dirroot . $module . '.php');
3604
                if ($res) {
3605
                    break;
3606
                }
3607
            }
3608
3609
            $mod = new $module($this->db);
3610
3611
            dol_syslog(get_class($this) . "::check_codefournisseur code_fournisseur=" . $this->code_fournisseur . " module=" . $module);
3612
            $result = $mod->verif($this->db, $this->code_fournisseur, $this, 1);
3613
            if ($result) {  // If error
3614
                $this->error = $mod->error;
3615
                $this->errors = $mod->errors;
3616
            }
3617
            return $result;
3618
        } else {
3619
            return 0;
3620
        }
3621
    }
3622
3623
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3624
    /**
3625
     *      Assigns a accounting code from the accounting code module.
3626
     *      Computed value is stored into this->code_compta or this->code_compta_fournisseur according to $type.
3627
     *      May be identical to the one entered or generated automatically. Currently, only the automatic generation is implemented.
3628
     *
3629
     *      @param  string  $type       Type of thirdparty ('customer' or 'supplier')
3630
     *      @return int                 0 if OK, <0 if $type is not valid
3631
     */
3632
    public function get_codecompta($type)
3633
    {
3634
		// phpcs:enable
3635
        global $conf;
3636
3637
        if (getDolGlobalString('SOCIETE_CODECOMPTA_ADDON')) {
3638
            $module = getDolGlobalString('SOCIETE_CODECOMPTA_ADDON');
3639
            $res = false;
3640
            $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
3641
            foreach ($dirsociete as $dirroot) {
3642
                $res = dol_include_once($dirroot . $module . '.php');
3643
                if ($res) {
3644
                    break;
3645
                }
3646
            }
3647
3648
            if ($res) {
3649
                $mod = new $module();
3650
3651
                // Set code count in $mod->code
3652
                $result = $mod->get_code($this->db, $this, $type);
3653
3654
                if ($type == 'customer') {
3655
                    $this->code_compta_client = $mod->code;
3656
                    $this->code_compta = $this->code_compta_client; // For backward compatibility
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Cl...s\Societe::$code_compta has been deprecated: Use $code_compta_client ( Ignorable by Annotation )

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

3656
                    /** @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...
3657
                } elseif ($type == 'supplier') {
3658
                    $this->code_compta_fournisseur = $mod->code;
3659
                }
3660
3661
                return $result;
3662
            } else {
3663
                $this->error = 'ErrorAccountancyCodeNotDefined';
3664
                return -1;
3665
            }
3666
        } else {
3667
            if ($type == 'customer') {
3668
                $this->code_compta_client = '';
3669
                $this->code_compta = '';
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Cl...s\Societe::$code_compta has been deprecated: Use $code_compta_client ( Ignorable by Annotation )

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

3669
                /** @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...
3670
            } elseif ($type == 'supplier') {
3671
                $this->code_compta_fournisseur = '';
3672
            }
3673
3674
            return 0;
3675
        }
3676
    }
3677
3678
    /**
3679
     *    Define parent company of current company
3680
     *
3681
     *    @param    int     $id     Id of thirdparty to set or '' to remove
3682
     *    @return   int             Return integer <0 if KO, >0 if OK
3683
     */
3684
    public function setParent($id)
3685
    {
3686
        dol_syslog(get_class($this) . '::setParent', LOG_DEBUG);
3687
3688
        if ($this->id) {
3689
            // Check if the id we want to add as parent has not already one parent that is the current id we try to update
3690
            if ($id > 0) {
3691
                $sameparent = $this->validateFamilyTree($id, $this->id, 0);
3692
                if ($sameparent < 0) {
3693
                    return -1;
3694
                }
3695
                if ($sameparent == 1) {
3696
                    setEventMessages('ParentCompanyToAddIsAlreadyAChildOfModifiedCompany', null, 'warnings');
3697
                    return -1;
3698
                }
3699
            }
3700
3701
            $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'societe SET parent = ' . ($id > 0 ? $id : 'null') . ' WHERE rowid = ' . ((int) $this->id);
3702
3703
            $resql = $this->db->query($sql);
3704
            if ($resql) {
3705
                $this->parent = $id;
3706
                return 1;
3707
            } else {
3708
                return -1;
3709
            }
3710
        }
3711
3712
        return -1;
3713
    }
3714
3715
    /**
3716
     *    Check if a thirdparty $idchild is or not inside the parents (or grand parents) of another thirdparty id $idparent.
3717
     *
3718
     *    @param    int     $idparent   Id of thirdparty to check
3719
     *    @param    int     $idchild    Id of thirdparty to compare to
3720
     *    @param    int     $counter    Counter to protect against infinite loops
3721
     *    @return   int                 Return integer <0 if KO, 0 if OK or 1 if at some level a parent company was the child to compare to
3722
     */
3723
    public function validateFamilyTree($idparent, $idchild, $counter = 0)
3724
    {
3725
        if ($counter > 100) {
3726
            dol_syslog("Too high level of parent - child for company. May be an infinite loop ?", LOG_WARNING);
3727
        }
3728
3729
        $sql = 'SELECT s.parent';
3730
        $sql .= ' FROM ' . MAIN_DB_PREFIX . 'societe as s';
3731
        $sql .= ' WHERE rowid = ' . ((int) $idparent);
3732
        $resql = $this->db->query($sql);
3733
        if ($resql) {
3734
            $obj    = $this->db->fetch_object($resql);
3735
3736
            if ($obj->parent == '') {
3737
                return 0;
3738
            } elseif ($obj->parent == $idchild) {
3739
                return 1;
3740
            } else {
3741
                $sameparent = $this->validateFamilyTree($obj->parent, $idchild, ($counter + 1));
3742
            }
3743
            return $sameparent;
3744
        } else {
3745
            return -1;
3746
        }
3747
    }
3748
3749
    /**
3750
     *  Get parents for company
3751
     *
3752
     * @param   int         $company_id     ID of company to search parent
3753
     * @param   array       $parents        List of companies ID found
3754
     * @return  array
3755
     */
3756
    public function getParentsForCompany($company_id, $parents = array())
3757
    {
3758
        global $langs;
3759
3760
        if ($company_id > 0) {
3761
            $sql = "SELECT parent FROM " . MAIN_DB_PREFIX . "societe WHERE rowid = " . ((int) $company_id);
3762
            $resql = $this->db->query($sql);
3763
            if ($resql) {
3764
                if ($obj = $this->db->fetch_object($resql)) {
3765
                    $parent = $obj->parent;
3766
                    if ($parent > 0 && !in_array($parent, $parents)) {
3767
                        $parents[] = $parent;
3768
                        return $this->getParentsForCompany($parent, $parents);
3769
                    } else {
3770
                        return $parents;
3771
                    }
3772
                }
3773
                $this->db->free($resql);
3774
            } else {
3775
                setEventMessage($langs->trans('GetCompanyParentsError', $this->db->lasterror()), 'errors');
3776
            }
3777
        }
3778
        // Return a default value when $company_id is not greater than 0
3779
        return array();
3780
    }
3781
3782
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3783
    /**
3784
     *  Returns if a profid should be verified to be unique
3785
     *
3786
     *  @param  int     $idprof     1,2,3,4,5,6 (Example: 1=siren, 2=siret, 3=naf, 4=rcs/rm, 5=eori, 6=idprof6)
3787
     *  @return boolean             true if the ID must be unique
3788
     */
3789
    public function id_prof_verifiable($idprof)
3790
    {
3791
		// phpcs:enable
3792
        global $conf;
3793
3794
        switch ($idprof) {
3795
            case 1:
3796
                $ret = (!getDolGlobalString('SOCIETE_IDPROF1_UNIQUE') ? false : true);
3797
                break;
3798
            case 2:
3799
                $ret = (!getDolGlobalString('SOCIETE_IDPROF2_UNIQUE') ? false : true);
3800
                break;
3801
            case 3:
3802
                $ret = (!getDolGlobalString('SOCIETE_IDPROF3_UNIQUE') ? false : true);
3803
                break;
3804
            case 4:
3805
                $ret = (!getDolGlobalString('SOCIETE_IDPROF4_UNIQUE') ? false : true);
3806
                break;
3807
            case 5:
3808
                $ret = (!getDolGlobalString('SOCIETE_IDPROF5_UNIQUE') ? false : true);
3809
                break;
3810
            case 6:
3811
                $ret = (!getDolGlobalString('SOCIETE_IDPROF6_UNIQUE') ? false : true);
3812
                break;
3813
            default:
3814
                $ret = false;
3815
        }
3816
3817
        return $ret;
3818
    }
3819
3820
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3821
    /**
3822
     *    Verify if a profid exists into database for others thirds
3823
     *
3824
     *    @param    string  $idprof     'idprof1','idprof2','idprof3','idprof4','idprof5','idprof6','email' (Example: idprof1=siren, idprof2=siret, idprof3=naf, idprof4=rcs/rm)
3825
     *    @param    string  $value      Value of profid
3826
     *    @param    int     $socid      Id of thirdparty to exclude (if update)
3827
     *    @return   boolean             True if exists, False if not
3828
     */
3829
    public function id_prof_exists($idprof, $value, $socid = 0)
3830
    {
3831
		// phpcs:enable
3832
        $field = $idprof;
3833
3834
        switch ($idprof) {  // For backward compatibility
3835
            case '1':
3836
            case 'idprof1':
3837
                $field = "siren";
3838
                break;
3839
            case '2':
3840
            case 'idprof2':
3841
                $field = "siret";
3842
                break;
3843
            case '3':
3844
            case 'idprof3':
3845
                $field = "ape";
3846
                break;
3847
            case '4':
3848
            case 'idprof4':
3849
                $field = "idprof4";
3850
                break;
3851
            case '5':
3852
                $field = "idprof5";
3853
                break;
3854
            case '6':
3855
                $field = "idprof6";
3856
                break;
3857
        }
3858
3859
        //Verify duplicate entries
3860
        $sql = "SELECT COUNT(*) as nb FROM " . MAIN_DB_PREFIX . "societe WHERE " . $field . " = '" . $this->db->escape($value) . "' AND entity IN (" . getEntity('societe') . ")";
3861
        if ($socid) {
3862
            $sql .= " AND rowid <> " . $socid;
3863
        }
3864
        $resql = $this->db->query($sql);
3865
        if ($resql) {
3866
            $obj = $this->db->fetch_object($resql);
3867
            $count = $obj->nb;
3868
        } else {
3869
            $count = 0;
3870
            print $this->db->error();
3871
        }
3872
        $this->db->free($resql);
3873
3874
        if ($count > 0) {
3875
            return true;
3876
        } else {
3877
            return false;
3878
        }
3879
    }
3880
3881
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3882
    /**
3883
     *  Check the validity of a professional identifier according to the country of the company (siren, siret, ...)
3884
     *
3885
     *  @param  int         $idprof         1,2,3,4 (Example: 1=siren,2=siret,3=naf,4=rcs/rm)
3886
     *  @param  Societe     $soc            Object societe
3887
     *  @return int                         Return integer <=0 if KO, >0 if OK
3888
     *  TODO better to have this in a lib than into a business class
3889
     */
3890
    public function id_prof_check($idprof, $soc)
3891
    {
3892
		// phpcs:enable
3893
        global $conf;
3894
3895
        // load the library necessary to check the professional identifiers
3896
        require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/profid.lib.php';
3897
3898
        $ok = 1;
3899
3900
        if (getDolGlobalString('MAIN_DISABLEPROFIDRULES')) {
3901
            return 1;
3902
        }
3903
3904
        // Check SIREN
3905
        if ($idprof == 1 && $soc->country_code == 'FR' && !isValidSiren($this->idprof1)) {
3906
            return -1;
3907
        }
3908
3909
        // Check SIRET
3910
        if ($idprof == 2 && $soc->country_code == 'FR' && !isValidSiret($this->idprof2)) {
3911
            return -1;
3912
        }
3913
3914
        //Verify CIF/NIF/NIE if pays ES
3915
        if ($idprof == 1 && $soc->country_code == 'ES') {
3916
            return isValidTinForES($this->idprof1);
3917
        }
3918
3919
        //Verify NIF if country is PT
3920
        if ($idprof == 1 && $soc->country_code == 'PT' && !isValidTinForPT($this->idprof1)) {
3921
            return -1;
3922
        }
3923
3924
        //Verify NIF if country is DZ
3925
        if ($idprof == 1 && $soc->country_code == 'DZ' && !isValidTinForDZ($this->idprof1)) {
3926
            return -1;
3927
        }
3928
3929
        //Verify ID Prof 1 if country is BE
3930
        if ($idprof == 1 && $soc->country_code == 'BE' && !isValidTinForBE($this->idprof1)) {
3931
            return -1;
3932
        }
3933
3934
        return $ok;
3935
    }
3936
3937
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3938
    /**
3939
     *   Return an url to check online a professional id or empty string
3940
     *
3941
     *   @param     int     $idprof         1,2,3,4 (Example: 1=siren,2=siret,3=naf,4=rcs/rm)
3942
     *   @param     Societe $thirdparty     Object thirdparty
3943
     *   @return    string                  Url or empty string if no URL known
3944
     *   TODO better in a lib than into business class
3945
     */
3946
    public function id_prof_url($idprof, $thirdparty)
3947
    {
3948
		// phpcs:enable
3949
        global $conf, $langs, $hookmanager;
3950
3951
        $url = '';
3952
        $action = '';
3953
3954
        $hookmanager->initHooks(array('idprofurl'));
3955
        $parameters = array('idprof' => $idprof, 'company' => $thirdparty);
3956
        $reshook = $hookmanager->executeHooks('getIdProfUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
3957
        if (empty($reshook)) {
3958
            if (getDolGlobalString('MAIN_DISABLEPROFIDRULES')) {
3959
                return '';
3960
            }
3961
3962
            // TODO Move links to validate professional ID into a dictionary table "country" + "link"
3963
            $strippedIdProf1 = str_replace(' ', '', $thirdparty->idprof1);
3964
            if ($idprof == 1 && $thirdparty->country_code == 'FR') {
3965
                $url = 'https://annuaire-entreprises.data.gouv.fr/entreprise/' . $strippedIdProf1; // See also http://avis-situation-sirene.insee.fr/
3966
            }
3967
            if ($idprof == 1 && ($thirdparty->country_code == 'GB' || $thirdparty->country_code == 'UK')) {
3968
                $url = 'https://beta.companieshouse.gov.uk/company/' . $strippedIdProf1;
3969
            }
3970
            if ($idprof == 1 && $thirdparty->country_code == 'ES') {
3971
                $url = 'http://www.e-informa.es/servlet/app/portal/ENTP/screen/SProducto/prod/ETIQUETA_EMPRESA/nif/' . $strippedIdProf1;
3972
            }
3973
            if ($idprof == 1 && $thirdparty->country_code == 'IN') {
3974
                $url = 'http://www.tinxsys.com/TinxsysInternetWeb/dealerControllerServlet?tinNumber=' . $strippedIdProf1 . ';&searchBy=TIN&backPage=searchByTin_Inter.jsp';
3975
            }
3976
            if ($idprof == 1 && $thirdparty->country_code == 'DZ') {
3977
                $url = 'http://nif.mfdgi.gov.dz/nif.asp?Nif=' . $strippedIdProf1;
3978
            }
3979
            if ($idprof == 1 && $thirdparty->country_code == 'PT') {
3980
                $url = 'http://www.nif.pt/' . $strippedIdProf1;
3981
            }
3982
3983
            if ($url) {
3984
                return '<a target="_blank" rel="noopener noreferrer" href="' . $url . '">' . $langs->trans("Check") . '</a>';
3985
            }
3986
        } else {
3987
            return $hookmanager->resPrint;
3988
        }
3989
3990
        return '';
3991
    }
3992
3993
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3994
    /**
3995
     *   Indicates if the company has projects
3996
     *
3997
     *   @return     bool      true if the company has projects, false otherwise
3998
     */
3999
    public function has_projects()
4000
    {
4001
		// phpcs:enable
4002
        $sql = "SELECT COUNT(*) as numproj FROM " . MAIN_DB_PREFIX . "projet WHERE fk_soc = " . ((int) $this->id);
4003
        $resql = $this->db->query($sql);
4004
        if ($resql) {
4005
            $obj = $this->db->fetch_object($resql);
4006
            $count = $obj->numproj;
4007
        } else {
4008
            $count = 0;
4009
            print $this->db->error();
4010
        }
4011
        $this->db->free($resql);
4012
        return ($count > 0);
4013
    }
4014
4015
4016
    /**
4017
     *  Load information for tab info
4018
     *
4019
     *  @param  int     $id     Id of thirdparty to load
4020
     *  @return void
4021
     */
4022
    public function info($id)
4023
    {
4024
        $sql = "SELECT s.rowid, s.nom as name, s.datec, tms as datem,";
4025
        $sql .= " fk_user_creat, fk_user_modif";
4026
        $sql .= " FROM " . MAIN_DB_PREFIX . "societe as s";
4027
        $sql .= " WHERE s.rowid = " . ((int) $id);
4028
4029
        $result = $this->db->query($sql);
4030
        if ($result) {
4031
            if ($this->db->num_rows($result)) {
4032
                $obj = $this->db->fetch_object($result);
4033
4034
                $this->id = $obj->rowid;
4035
4036
                $this->user_creation_id = $obj->fk_user_creat;
4037
                $this->user_modification_id = $obj->fk_user_modif;
4038
                $this->date_creation     = $this->db->jdate($obj->datec);
4039
                $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
4040
4041
                $this->ref = $obj->name;
4042
            }
4043
4044
            $this->db->free($result);
4045
        } else {
4046
            dol_print_error($this->db);
4047
        }
4048
    }
4049
4050
    /**
4051
     *  Check if third party is a company (Business) or an end user (Consumer)
4052
     *
4053
     *  @return     boolean     if a company: true || if a user: false
4054
     */
4055
    public function isACompany()
4056
    {
4057
        // Define if third party is treated as company (or not) when nature is unknown
4058
        $isACompany = getDolGlobalInt('MAIN_UNKNOWN_CUSTOMERS_ARE_COMPANIES');
4059
4060
        // Now try to guess using different tips
4061
        if (!empty($this->tva_intra)) {
4062
            $isACompany = 1;
4063
        } elseif (!empty($this->idprof1) || !empty($this->idprof2) || !empty($this->idprof3) || !empty($this->idprof4) || !empty($this->idprof5) || !empty($this->idprof6)) {
4064
            $isACompany = 1;
4065
        } else {
4066
            if (!getDolGlobalString('MAIN_CUSTOMERS_ARE_COMPANIES_EVEN_IF_SET_AS_INDIVIDUAL')) {
4067
                // TODO Add a field is_a_company into dictionary
4068
                if (preg_match('/^TE_PRIVATE/', $this->typent_code)) {
4069
                    $isACompany = 0;
4070
                } else {
4071
                    $isACompany = 1;
4072
                }
4073
            } else {
4074
                $isACompany = 1;
4075
            }
4076
        }
4077
4078
        return (bool) $isACompany;
4079
    }
4080
4081
    /**
4082
     *  Return if a company is inside the EEC (European Economic Community)
4083
     *
4084
     *  @return     boolean     true = country inside EEC, false = country outside EEC
4085
     */
4086
    public function isInEEC()
4087
    {
4088
        require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/company.lib.php';
4089
        return isInEEC($this);
4090
    }
4091
4092
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
4093
    /**
4094
     *  Load the list of provider categories
4095
     *
4096
     *  @return    int      0 if success, <> 0 if error
4097
     */
4098
    public function LoadSupplierCateg()
4099
    {
4100
		// phpcs:enable
4101
        $this->SupplierCategories = array();
4102
        $sql = "SELECT rowid, label";
4103
        $sql .= " FROM " . MAIN_DB_PREFIX . "categorie";
4104
        $sql .= " WHERE type = " . Categorie::TYPE_SUPPLIER;
4105
4106
        $resql = $this->db->query($sql);
4107
        if ($resql) {
4108
            while ($obj = $this->db->fetch_object($resql)) {
4109
                $this->SupplierCategories[$obj->rowid] = $obj->label;
4110
            }
4111
            return 0;
4112
        } else {
4113
            return -1;
4114
        }
4115
    }
4116
4117
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
4118
    /**
4119
     *  Insert link supplier - category
4120
     *
4121
     *  @param  int     $categorie_id       Id of category
4122
     *  @return int                         0 if success, <> 0 if error
4123
     */
4124
    public function AddFournisseurInCategory($categorie_id)
4125
    {
4126
		// phpcs:enable
4127
        if ($categorie_id > 0 && $this->id > 0) {
4128
            $sql = "INSERT INTO " . MAIN_DB_PREFIX . "categorie_fournisseur (fk_categorie, fk_soc) ";
4129
            $sql .= " VALUES (" . ((int) $categorie_id) . ", " . ((int) $this->id) . ")";
4130
4131
            if ($resql = $this->db->query($sql)) {
4132
                return 0;
4133
            }
4134
        } else {
4135
            return 0;
4136
        }
4137
        return -1;
4138
    }
4139
4140
    /**
4141
     *  Return number of mass Emailing received by this contacts with its email
4142
     *
4143
     *  @return       int     Number of EMailings
4144
     */
4145
    public function getNbOfEMailings()
4146
    {
4147
        $sql = "SELECT count(mc.email) as nb";
4148
        $sql .= " FROM " . MAIN_DB_PREFIX . "mailing_cibles as mc, " . MAIN_DB_PREFIX . "mailing as m";
4149
        $sql .= " WHERE mc.fk_mailing=m.rowid AND mc.email = '" . $this->db->escape($this->email) . "' ";
4150
        $sql .= " AND m.entity IN (" . getEntity($this->element) . ") AND mc.statut NOT IN (-1,0)"; // -1 error, 0 not sent, 1 sent with success
4151
4152
        $resql = $this->db->query($sql);
4153
        if ($resql) {
4154
            $obj = $this->db->fetch_object($resql);
4155
            $nb = $obj->nb;
4156
4157
            $this->db->free($resql);
4158
            return $nb;
4159
        } else {
4160
            $this->error = $this->db->error();
4161
            return -1;
4162
        }
4163
    }
4164
4165
    /**
4166
     *  Set "blacklist" mailing status
4167
     *
4168
     *  @param  int     $no_email   1=Do not send mailing, 0=Ok to receive mailing
4169
     *  @return int                 Return integer <0 if KO, >0 if OK
4170
     */
4171
    public function setNoEmail($no_email)
4172
    {
4173
        $error = 0;
4174
4175
        // Update mass emailing flag into table mailing_unsubscribe
4176
        if ($this->email) {
4177
            $this->db->begin();
4178
4179
            if ($no_email) {
4180
                $sql = "SELECT COUNT(rowid) as nb FROM " . MAIN_DB_PREFIX . "mailing_unsubscribe WHERE entity IN (" . getEntity('mailing', 0) . ") AND email = '" . $this->db->escape($this->email) . "'";
4181
                $resql = $this->db->query($sql);
4182
                if ($resql) {
4183
                    $obj = $this->db->fetch_object($resql);
4184
                    $noemail = $obj->nb;
4185
                    if (empty($noemail)) {
4186
                        $sql = "INSERT INTO " . MAIN_DB_PREFIX . "mailing_unsubscribe(email, entity, date_creat) VALUES ('" . $this->db->escape($this->email) . "', " . getEntity('mailing', 0) . ", '" . $this->db->idate(dol_now()) . "')";
4187
                        $resql = $this->db->query($sql);
4188
                        if (!$resql) {
4189
                            $error++;
4190
                            $this->error = $this->db->lasterror();
4191
                            $this->errors[] = $this->error;
4192
                        }
4193
                    }
4194
                } else {
4195
                    $error++;
4196
                    $this->error = $this->db->lasterror();
4197
                    $this->errors[] = $this->error;
4198
                }
4199
            } else {
4200
                $sql = "DELETE FROM " . MAIN_DB_PREFIX . "mailing_unsubscribe WHERE email = '" . $this->db->escape($this->email) . "' AND entity IN (" . getEntity('mailing', 0) . ")";
4201
                $resql = $this->db->query($sql);
4202
                if (!$resql) {
4203
                    $error++;
4204
                    $this->error = $this->db->lasterror();
4205
                    $this->errors[] = $this->error;
4206
                }
4207
            }
4208
4209
            if (empty($error)) {
4210
                $this->no_email = $no_email;
4211
                $this->db->commit();
4212
                return 1;
4213
            } else {
4214
                $this->db->rollback();
4215
                return $error * -1;
4216
            }
4217
        }
4218
4219
        return 0;
4220
    }
4221
4222
    /**
4223
     *  get "blacklist" mailing status
4224
     *  set no_email attribute to 1 or 0
4225
     *
4226
     *  @return int                 Return integer <0 if KO, >0 if OK
4227
     */
4228
    public function getNoEmail()
4229
    {
4230
        if ($this->email) {
4231
            $sql = "SELECT COUNT(rowid) as nb FROM " . MAIN_DB_PREFIX . "mailing_unsubscribe WHERE entity IN (" . getEntity('mailing') . ") AND email = '" . $this->db->escape($this->email) . "'";
4232
            $resql = $this->db->query($sql);
4233
            if ($resql) {
4234
                $obj = $this->db->fetch_object($resql);
4235
                $this->no_email = $obj->nb;
4236
                return 1;
4237
            } else {
4238
                $this->error = $this->db->lasterror();
4239
                $this->errors[] = $this->error;
4240
                return -1;
4241
            }
4242
        }
4243
        return 0;
4244
    }
4245
4246
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
4247
    /**
4248
     *  Create a third party into database from a member object
4249
     *
4250
     *  @param  Adherent    $member         Object member
4251
     *  @param  string      $socname        Name of third party to force
4252
     *  @param  string      $socalias       Alias name of third party to force
4253
     *  @param  string      $customercode   Customer code
4254
     *  @return int                         Return integer <0 if KO, id of created account if OK
4255
     */
4256
    public function create_from_member(Adherent $member, $socname = '', $socalias = '', $customercode = '')
4257
    {
4258
		// phpcs:enable
4259
        global $conf, $user, $langs;
4260
4261
        dol_syslog(get_class($this) . "::create_from_member", LOG_DEBUG);
4262
        $fullname = $member->getFullName($langs);
4263
4264
        if ($member->morphy == 'mor') {
4265
            if (empty($socname)) {
4266
                $socname = $member->company ? $member->company : $member->societe;
4267
            }
4268
            if (!empty($fullname) && empty($socalias)) {
4269
                $socalias = $fullname;
4270
            }
4271
        } elseif (empty($socname) && $member->morphy == 'phy') {
4272
            if (empty($socname)) {
4273
                $socname = $fullname;
4274
            }
4275
            if (!empty($member->company) && empty($socalias)) {
4276
                $socalias = $member->company;
4277
            }
4278
        }
4279
4280
        $name = $socname;
4281
        $alias = $socalias ? $socalias : '';
4282
4283
        // Positionne parameters
4284
        $this->nom = $name; // TODO deprecated
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

4284
        /** @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...
4285
        $this->name = $name;
4286
        $this->name_alias = $alias;
4287
        $this->address = $member->address;
4288
        $this->zip = $member->zip;
4289
        $this->town = $member->town;
4290
        $this->country_code = $member->country_code;
4291
        $this->country_id = $member->country_id;
4292
        $this->phone = $member->phone; // Prof phone
4293
        $this->email = $member->email;
4294
        $this->socialnetworks = $member->socialnetworks;
4295
        $this->entity = $member->entity;
4296
4297
        $this->client = 1; // A member is a customer by default
4298
        $this->code_client = ($customercode ? $customercode : -1);
4299
        $this->code_fournisseur = '-1';
4300
        $this->typent_code = ($member->morphy == 'phy' ? 'TE_PRIVATE' : 0);
4301
        $this->typent_id = $this->typent_code ? dol_getIdFromCode($this->db, $this->typent_code, 'c_typent', 'id', 'code') : 0;
4302
4303
        $this->db->begin();
4304
4305
        // Cree et positionne $this->id
4306
        $result = $this->create($user);
4307
4308
        if ($result >= 0) {
4309
            // Auto-create contact on thirdparty creation
4310
            if (getDolGlobalString('THIRDPARTY_DEFAULT_CREATE_CONTACT')) {
4311
                // Fill fields needed by contact
4312
                $this->name_bis = $member->lastname;
4313
                $this->firstname = $member->firstname;
4314
                $this->civility_id = $member->civility_id;
4315
4316
                dol_syslog("We ask to create a contact/address too", LOG_DEBUG);
4317
                $result = $this->create_individual($user);
4318
4319
                if ($result < 0) {
4320
                    setEventMessages($this->error, $this->errors, 'errors');
4321
                    $this->db->rollback();
4322
                    return -1;
4323
                }
4324
            }
4325
4326
            $sql = "UPDATE " . MAIN_DB_PREFIX . "adherent";
4327
            $sql .= " SET fk_soc = " . ((int) $this->id);
4328
            $sql .= " WHERE rowid = " . ((int) $member->id);
4329
4330
            $resql = $this->db->query($sql);
4331
            if ($resql) {
4332
                $this->db->commit();
4333
                return $this->id;
4334
            } else {
4335
                $this->error = $this->db->error();
4336
4337
                $this->db->rollback();
4338
                return -1;
4339
            }
4340
        } else {
4341
            // $this->error deja positionne
4342
            dol_syslog(get_class($this) . "::create_from_member - 2 - " . $this->error . " - " . implode(',', $this->errors), LOG_ERR);
4343
4344
            $this->db->rollback();
4345
            return $result;
4346
        }
4347
    }
4348
4349
    /**
4350
     *  Set properties with value into $conf
4351
     *
4352
     *  @param  Conf    $conf       Conf object (possibility to use another entity)
4353
     *  @return void
4354
     */
4355
    public function setMysoc(Conf $conf)
4356
    {
4357
        global $langs;
4358
4359
        $this->id = 0;
4360
        $this->entity = $conf->entity;
4361
        $this->name = getDolGlobalString('MAIN_INFO_SOCIETE_NOM');
4362
        $this->nom = $this->name; // deprecated
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

4362
        /** @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...
4363
        $this->address = getDolGlobalString('MAIN_INFO_SOCIETE_ADDRESS');
4364
        $this->zip = getDolGlobalString('MAIN_INFO_SOCIETE_ZIP');
4365
        $this->town = getDolGlobalString('MAIN_INFO_SOCIETE_TOWN');
4366
        $this->region_code = getDolGlobalString('MAIN_INFO_SOCIETE_REGION');
4367
4368
        $this->socialobject = getDolGlobalString('MAIN_INFO_SOCIETE_OBJECT');
4369
4370
        $this->note_private = getDolGlobalString('MAIN_INFO_SOCIETE_NOTE');
4371
4372
        // We define country_id, country_code and country
4373
        $country_id = 0;
4374
        $country_code = $country_label = '';
4375
        if (getDolGlobalString('MAIN_INFO_SOCIETE_COUNTRY')) {
4376
            $tmp = explode(':', getDolGlobalString('MAIN_INFO_SOCIETE_COUNTRY'));
4377
            $country_id =  (is_numeric($tmp[0])) ? (int) $tmp[0] : 0;
4378
            if (!empty($tmp[1])) {   // If $conf->global->MAIN_INFO_SOCIETE_COUNTRY is "id:code:label"
4379
                $country_code = $tmp[1];
4380
                $country_label = $tmp[2];
4381
            } else {
4382
                // For backward compatibility
4383
                dol_syslog("Your country setup use an old syntax. Reedit it using setup area.", LOG_WARNING);
4384
                include_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
4385
                $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
4386
                $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
4387
            }
4388
        }
4389
        $this->country_id = $country_id;
4390
        $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...
4391
        $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...
4392
        if (is_object($langs)) {
4393
            $this->country = ($langs->trans('Country' . $country_code) != 'Country' . $country_code) ? $langs->trans('Country' . $country_code) : $country_label;
4394
        }
4395
4396
        //TODO This could be replicated for region but function `getRegion` didn't exist, so I didn't added it.
4397
        // We define state_id, state_code and state
4398
        $state_id = 0;
4399
        $state_code = $state_label = '';
4400
        if (getDolGlobalString('MAIN_INFO_SOCIETE_STATE')) {
4401
            $tmp = explode(':', getDolGlobalString('MAIN_INFO_SOCIETE_STATE'));
4402
            $state_id = $tmp[0];
4403
            if (!empty($tmp[1])) {   // If $conf->global->MAIN_INFO_SOCIETE_STATE is "id:code:label"
4404
                $state_code = $tmp[1];
4405
                $state_label = $tmp[2];
4406
            } else { // For backward compatibility
4407
                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);
4408
                include_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
4409
                $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
4410
                $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
4411
            }
4412
        }
4413
        $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...
4414
        $this->state_code = $state_code;
4415
        $this->state = $state_label;
4416
        if (is_object($langs)) {
4417
            $this->state = ($langs->trans('State' . $state_code) != 'State' . $state_code) ? $langs->trans('State' . $state_code) : $state_label;
4418
        }
4419
4420
        $this->phone = getDolGlobalString('MAIN_INFO_SOCIETE_TEL');
4421
        $this->phone_mobile = getDolGlobalString('MAIN_INFO_SOCIETE_MOBILE');
4422
        $this->fax = getDolGlobalString('MAIN_INFO_SOCIETE_FAX');
4423
        $this->url = getDolGlobalString('MAIN_INFO_SOCIETE_WEB');
4424
4425
        // Social networks
4426
        $facebook_url = getDolGlobalString('MAIN_INFO_SOCIETE_FACEBOOK_URL');
4427
        $twitter_url = getDolGlobalString('MAIN_INFO_SOCIETE_TWITTER_URL');
4428
        $linkedin_url = getDolGlobalString('MAIN_INFO_SOCIETE_LINKEDIN_URL');
4429
        $instagram_url = getDolGlobalString('MAIN_INFO_SOCIETE_INSTAGRAM_URL');
4430
        $youtube_url = getDolGlobalString('MAIN_INFO_SOCIETE_YOUTUBE_URL');
4431
        $github_url = getDolGlobalString('MAIN_INFO_SOCIETE_GITHUB_URL');
4432
        $this->socialnetworks = array();
4433
        if (!empty($facebook_url)) {
4434
            $this->socialnetworks['facebook'] = $facebook_url;
4435
        }
4436
        if (!empty($twitter_url)) {
4437
            $this->socialnetworks['twitter'] = $twitter_url;
4438
        }
4439
        if (!empty($linkedin_url)) {
4440
            $this->socialnetworks['linkedin'] = $linkedin_url;
4441
        }
4442
        if (!empty($instagram_url)) {
4443
            $this->socialnetworks['instagram'] = $instagram_url;
4444
        }
4445
        if (!empty($youtube_url)) {
4446
            $this->socialnetworks['youtube'] = $youtube_url;
4447
        }
4448
        if (!empty($github_url)) {
4449
            $this->socialnetworks['github'] = $github_url;
4450
        }
4451
4452
        // Id prof generiques
4453
        $this->idprof1 = getDolGlobalString('MAIN_INFO_SIREN');
4454
        $this->idprof2 = getDolGlobalString('MAIN_INFO_SIRET');
4455
        $this->idprof3 = getDolGlobalString('MAIN_INFO_APE');
4456
        $this->idprof4 = getDolGlobalString('MAIN_INFO_RCS');
4457
        $this->idprof5 = getDolGlobalString('MAIN_INFO_PROFID5');
4458
        $this->idprof6 = getDolGlobalString('MAIN_INFO_PROFID6');
4459
        $this->tva_intra = getDolGlobalString('MAIN_INFO_TVAINTRA'); // VAT number, not necessarily INTRA.
4460
        $this->managers = getDolGlobalString('MAIN_INFO_SOCIETE_MANAGERS');
4461
        $this->capital = is_numeric(getDolGlobalString('MAIN_INFO_CAPITAL')) ? (float) price2num(getDolGlobalString('MAIN_INFO_CAPITAL')) : 0;
4462
        $this->forme_juridique_code = getDolGlobalString('MAIN_INFO_SOCIETE_FORME_JURIDIQUE');
4463
        $this->email = getDolGlobalString('MAIN_INFO_SOCIETE_MAIL');
4464
        $this->default_lang = getDolGlobalString('MAIN_LANG_DEFAULT', 'auto');
4465
        $this->logo = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO');
4466
        $this->logo_small = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO_SMALL');
4467
        $this->logo_mini = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO_MINI');
4468
        $this->logo_squarred = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO_SQUARRED');
4469
        $this->logo_squarred_small = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO_SQUARRED_SMALL');
4470
        $this->logo_squarred_mini = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO_SQUARRED_MINI');
4471
4472
        // Define if company use vat or not
4473
        $this->tva_assuj = getDolGlobalInt('FACTURE_TVAOPTION');
4474
4475
        // Define if company use local taxes
4476
        $this->localtax1_assuj = ((isset($conf->global->FACTURE_LOCAL_TAX1_OPTION) && (getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') == '1' || getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') == 'localtax1on')) ? 1 : 0);
4477
        $this->localtax2_assuj = ((isset($conf->global->FACTURE_LOCAL_TAX2_OPTION) && (getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') == '1' || getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') == 'localtax2on')) ? 1 : 0);
4478
    }
4479
4480
    /**
4481
     *  Initialise an instance with random values.
4482
     *  Used to build previews or test instances.
4483
     *  id must be 0 if object instance is a specimen.
4484
     *
4485
     *  @return int >0 if ok
4486
     */
4487
    public function initAsSpecimen()
4488
    {
4489
        $now = dol_now();
4490
4491
        // Initialize parameters
4492
        $this->id = 0;
4493
        $this->entity = 1;
4494
        $this->name = 'THIRDPARTY SPECIMEN ' . dol_print_date($now, 'dayhourlog');
4495
        $this->nom = $this->name; // For backward compatibility
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

4495
        /** @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...
4496
        $this->ref_ext = 'Ref ext';
4497
        $this->specimen = 1;
4498
        $this->address = '21 jump street';
4499
        $this->zip = '99999';
4500
        $this->town = 'MyTown';
4501
        $this->state_id = 1;
4502
        $this->state_code = 'AA';
4503
        $this->state = 'MyState';
4504
        $this->country_id = 1;
4505
        $this->country_code = 'FR';
4506
        $this->email = '[email protected]';
4507
        $this->socialnetworks = array(
4508
            'skype' => 'skypepseudo',
4509
            'twitter' => 'twitterpseudo',
4510
            'facebook' => 'facebookpseudo',
4511
            'linkedin' => 'linkedinpseudo',
4512
        );
4513
        $this->url = 'http://www.specimen.com';
4514
4515
        $this->phone = '0909090901';
4516
        $this->phone_mobile = '0909090901';
4517
        $this->fax = '0909090909';
4518
4519
        $this->code_client = 'CC-' . dol_print_date($now, 'dayhourlog');
4520
        $this->code_fournisseur = 'SC-' . dol_print_date($now, 'dayhourlog');
4521
        $this->capital = 10000;
4522
        $this->client = 1;
4523
        $this->prospect = 1;
4524
        $this->fournisseur = 1;
4525
        $this->tva_assuj = 1;
4526
        $this->tva_intra = 'EU1234567';
4527
        $this->note_public = 'This is a comment (public)';
4528
        $this->note_private = 'This is a comment (private)';
4529
4530
        $this->idprof1 = 'idprof1';
4531
        $this->idprof2 = 'idprof2';
4532
        $this->idprof3 = 'idprof3';
4533
        $this->idprof4 = 'idprof4';
4534
        $this->idprof5 = 'idprof5';
4535
        $this->idprof6 = 'idprof6';
4536
4537
        return 1;
4538
    }
4539
4540
    /**
4541
     *  Check if we must use localtax feature or not according to country (country of $mysoc in most cases).
4542
     *
4543
     *  @param      int     $localTaxNum    To get info for only localtax1 or localtax2
4544
     *  @return     boolean                 true or false
4545
     */
4546
    public function useLocalTax($localTaxNum = 0)
4547
    {
4548
        $sql  = "SELECT t.localtax1, t.localtax2";
4549
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_tva as t, " . MAIN_DB_PREFIX . "c_country as c";
4550
        $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '" . $this->db->escape($this->country_code) . "'";
4551
        $sql .= " AND t.active = 1";
4552
        $sql .= " AND t.entity IN (" . getEntity('c_tva') . ")";
4553
        if (empty($localTaxNum)) {
4554
            $sql .= " AND (t.localtax1_type <> '0' OR t.localtax2_type <> '0')";
4555
        } elseif ($localTaxNum == 1) {
4556
            $sql .= " AND t.localtax1_type <> '0'";
4557
        } elseif ($localTaxNum == 2) {
4558
            $sql .= " AND t.localtax2_type <> '0'";
4559
        }
4560
4561
        $resql = $this->db->query($sql);
4562
        if ($resql) {
4563
            return ($this->db->num_rows($resql) > 0);
4564
        } else {
4565
            return false;
4566
        }
4567
    }
4568
4569
    /**
4570
     *  Check if we must use NPR Vat (french stupid rule) or not according to country (country of $mysoc in most cases).
4571
     *
4572
     *  @return     boolean                 true or false
4573
     */
4574
    public function useNPR()
4575
    {
4576
        $sql  = "SELECT t.rowid";
4577
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_tva as t, " . MAIN_DB_PREFIX . "c_country as c";
4578
        $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '" . $this->db->escape($this->country_code) . "'";
4579
        $sql .= " AND t.active = 1 AND t.recuperableonly = 1";
4580
        $sql .= " AND t.entity IN (" . getEntity('c_tva') . ")";
4581
4582
        dol_syslog("useNPR", LOG_DEBUG);
4583
        $resql = $this->db->query($sql);
4584
        if ($resql) {
4585
            return ($this->db->num_rows($resql) > 0);
4586
        } else {
4587
            return false;
4588
        }
4589
    }
4590
4591
    /**
4592
     *  Check if we must use revenue stamps feature or not according to country (country of $mysocin most cases).
4593
     *  Table c_revenuestamp contains the country and value of stamp per invoice.
4594
     *
4595
     *  @return     boolean         true or false
4596
     */
4597
    public function useRevenueStamp()
4598
    {
4599
        $sql  = "SELECT COUNT(*) as nb";
4600
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_revenuestamp as r, " . MAIN_DB_PREFIX . "c_country as c";
4601
        $sql .= " WHERE r.fk_pays = c.rowid AND c.code = '" . $this->db->escape($this->country_code) . "'";
4602
        $sql .= " AND r.active = 1";
4603
4604
        dol_syslog("useRevenueStamp", LOG_DEBUG);
4605
        $resql = $this->db->query($sql);
4606
        if ($resql) {
4607
            $obj = $this->db->fetch_object($resql);
4608
            return (($obj->nb > 0) ? true : false);
4609
        } else {
4610
            $this->error = $this->db->lasterror();
4611
            return false;
4612
        }
4613
    }
4614
4615
    /**
4616
     *  Return prostect level
4617
     *
4618
     *  @return     string        Label of prospect status
4619
     */
4620
    public function getLibProspLevel()
4621
    {
4622
        return $this->LibProspLevel($this->fk_prospectlevel);
4623
    }
4624
4625
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
4626
    /**
4627
     *  Return label of prospect level
4628
     *
4629
     *  @param  string  $fk_prospectlevel       Prospect level
4630
     *  @return string                          label of level
4631
     */
4632
    public function LibProspLevel($fk_prospectlevel)
4633
    {
4634
		// phpcs:enable
4635
        global $langs;
4636
4637
        $label = '';
4638
        if ($fk_prospectlevel != '') {
4639
            $label = $langs->trans("ProspectLevel" . $fk_prospectlevel);
4640
            // If label is not found in language file, we get label from cache/database
4641
            if ($label == "ProspectLevel" . $fk_prospectlevel) {
4642
                $label = $langs->getLabelFromKey($this->db, $fk_prospectlevel, 'c_prospectlevel', 'code', 'label');
4643
            }
4644
        }
4645
4646
        return $label;
4647
    }
4648
4649
    /**
4650
     *  Return status of prospect
4651
     *
4652
     *  @param  int     $mode       0=label long, 1=label short, 2=Picto + Label short, 3=Picto, 4=Picto + Label long
4653
     *  @param  string  $label      Label to use for status for added status
4654
     *  @return string              Label
4655
     */
4656
    public function getLibProspCommStatut($mode = 0, $label = '')
4657
    {
4658
        return $this->LibProspCommStatut($this->stcomm_id, $mode, $label, $this->stcomm_picto);
4659
    }
4660
4661
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
4662
    /**
4663
     *  Return label of a given status
4664
     *
4665
     *  @param  int|string  $status         Id or code for prospection status
4666
     *  @param  int         $mode           0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto
4667
     *  @param  string      $label          Label to use for status for added status
4668
     *  @param  string      $picto          Name of image file to show ('filenew', ...)
4669
     *                                      If no extension provided, we use '.png'. Image must be stored into theme/xxx/img directory.
4670
     *                                      Example: picto.png                  if picto.png is stored into htdocs/theme/mytheme/img
4671
     *                                      Example: picto.png@mymodule         if picto.png is stored into htdocs/mymodule/img
4672
     *                                      Example: /mydir/mysubdir/picto.png  if picto.png is stored into htdocs/mydir/mysubdir (pictoisfullpath must be set to 1)
4673
     *  @return string                      Label of prospection status
4674
     */
4675
    public function LibProspCommStatut($status, $mode = 0, $label = '', $picto = '')
4676
    {
4677
		// phpcs:enable
4678
        global $langs;
4679
4680
        $langs->load('customers');
4681
4682
        if ($mode == 2) {
4683
            if ($status == '-1' || $status == 'ST_NO') {
4684
                return img_action($langs->trans("StatusProspect-1"), -1, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect-1");
4685
            } elseif ($status == '0' || $status == 'ST_NEVER') {
4686
                return img_action($langs->trans("StatusProspect0"), 0, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect0");
4687
            } elseif ($status == '1' || $status == 'ST_TODO') {
4688
                return img_action($langs->trans("StatusProspect1"), 1, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect1");
4689
            } elseif ($status == '2' || $status == 'ST_PEND') {
4690
                return img_action($langs->trans("StatusProspect2"), 2, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect2");
4691
            } elseif ($status == '3' || $status == 'ST_DONE') {
4692
                return img_action($langs->trans("StatusProspect3"), 3, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect3");
4693
            } else {
4694
                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);
4695
            }
4696
        } elseif ($mode == 3) {
4697
            if ($status == '-1' || $status == 'ST_NO') {
4698
                return img_action($langs->trans("StatusProspect-1"), -1, $picto, 'class="inline-block valignmiddle"');
4699
            } elseif ($status == '0' || $status == 'ST_NEVER') {
4700
                return img_action($langs->trans("StatusProspect0"), 0, $picto, 'class="inline-block valignmiddle"');
4701
            } elseif ($status == '1' || $status == 'ST_TODO') {
4702
                return img_action($langs->trans("StatusProspect1"), 1, $picto, 'class="inline-block valignmiddle"');
4703
            } elseif ($status == '2' || $status == 'ST_PEND') {
4704
                return img_action($langs->trans("StatusProspect2"), 2, $picto, 'class="inline-block valignmiddle"');
4705
            } elseif ($status == '3' || $status == 'ST_DONE') {
4706
                return img_action($langs->trans("StatusProspect3"), 3, $picto, 'class="inline-block valignmiddle"');
4707
            } else {
4708
                return img_action(($langs->trans("StatusProspect" . $status) != "StatusProspect" . $status) ? $langs->trans("StatusProspect" . $status) : $label, 0, $picto, 'class="inline-block valignmiddle"');
4709
            }
4710
        } elseif ($mode == 4) {
4711
            if ($status == '-1' || $status == 'ST_NO') {
4712
                return img_action($langs->trans("StatusProspect-1"), -1, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect-1");
4713
            } elseif ($status == '0' || $status == 'ST_NEVER') {
4714
                return img_action($langs->trans("StatusProspect0"), 0, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect0");
4715
            } elseif ($status == '1' || $status == 'ST_TODO') {
4716
                return img_action($langs->trans("StatusProspect1"), 1, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect1");
4717
            } elseif ($status == '2' || $status == 'ST_PEND') {
4718
                return img_action($langs->trans("StatusProspect2"), 2, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect2");
4719
            } elseif ($status == '3' || $status == 'ST_DONE') {
4720
                return img_action($langs->trans("StatusProspect3"), 3, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect3");
4721
            } else {
4722
                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);
4723
            }
4724
        }
4725
4726
        return "Error, mode/status not found";
4727
    }
4728
4729
    /**
4730
     *  Return amount of proposal not yet paid and total an dlist of all proposals
4731
     *
4732
     *  @param     string      $mode    'customer' or 'supplier'
4733
     *  @return    array                array('opened'=>Amount including tax that remains to pay, 'total_ht'=>Total amount without tax of all objects paid or not, 'total_ttc'=>Total amount including tax of all object paid or not)
4734
     */
4735
    public function getOutstandingProposals($mode = 'customer')
4736
    {
4737
        $table = 'propal';
4738
        if ($mode == 'supplier') {
4739
            $table = 'supplier_proposal';
4740
        }
4741
4742
        $sql  = "SELECT rowid, ref, total_ht, total_ttc, fk_statut as status FROM " . MAIN_DB_PREFIX . $table . " as f";
4743
        $sql .= " WHERE fk_soc = " . ((int) $this->id);
4744
        if ($mode == 'supplier') {
4745
            $sql .= " AND entity IN (" . getEntity('supplier_proposal') . ")";
4746
        } else {
4747
            $sql .= " AND entity IN (" . getEntity('propal') . ")";
4748
        }
4749
4750
        dol_syslog("getOutstandingProposals for fk_soc = " . ((int) $this->id), LOG_DEBUG);
4751
4752
        $resql = $this->db->query($sql);
4753
        if ($resql) {
4754
            $outstandingOpened = 0;
4755
            $outstandingTotal = 0;
4756
            $outstandingTotalIncTax = 0;
4757
            $arrayofref = array();
4758
            while ($obj = $this->db->fetch_object($resql)) {
4759
                $arrayofref[$obj->rowid] = $obj->ref;
4760
                $outstandingTotal += $obj->total_ht;
4761
                $outstandingTotalIncTax += $obj->total_ttc;
4762
                if ($obj->status != 0) {
4763
                    // Not a draft
4764
                    $outstandingOpened += $obj->total_ttc;
4765
                }
4766
            }
4767
            return array('opened' => $outstandingOpened, 'total_ht' => $outstandingTotal, 'total_ttc' => $outstandingTotalIncTax, 'refs' => $arrayofref); // 'opened' is 'incl taxes'
4768
        } else {
4769
            return array();
4770
        }
4771
    }
4772
4773
    /**
4774
     *  Return amount of order not yet paid and total and list of all orders
4775
     *
4776
     *  @param     string      $mode    'customer' or 'supplier'
4777
     *  @return    array                array('opened'=>Amount including tax that remains to pay, 'total_ht'=>Total amount without tax of all objects paid or not, 'total_ttc'=>Total amount including tax of all object paid or not)
4778
     */
4779
    public function getOutstandingOrders($mode = 'customer')
4780
    {
4781
        $table = 'commande';
4782
        if ($mode == 'supplier') {
4783
            $table = 'commande_fournisseur';
4784
        }
4785
4786
        $sql  = "SELECT rowid, ref, total_ht, total_ttc, fk_statut as status FROM " . MAIN_DB_PREFIX . $table . " as f";
4787
        $sql .= " WHERE fk_soc = " . ((int) $this->id);
4788
        if ($mode == 'supplier') {
4789
            $sql .= " AND entity IN (" . getEntity('supplier_order') . ")";
4790
        } else {
4791
            $sql .= " AND entity IN (" . getEntity('commande') . ")";
4792
        }
4793
4794
        dol_syslog("getOutstandingOrders", LOG_DEBUG);
4795
        $resql = $this->db->query($sql);
4796
        if ($resql) {
4797
            $outstandingOpened = 0;
4798
            $outstandingTotal = 0;
4799
            $outstandingTotalIncTax = 0;
4800
            $arrayofref = array();
4801
            while ($obj = $this->db->fetch_object($resql)) {
4802
                $arrayofref[$obj->rowid] = $obj->ref;
4803
                $outstandingTotal += $obj->total_ht;
4804
                $outstandingTotalIncTax += $obj->total_ttc;
4805
                if ($obj->status != 0) {
4806
                    // Not a draft
4807
                    $outstandingOpened += $obj->total_ttc;
4808
                }
4809
            }
4810
            return array('opened' => $outstandingOpened, 'total_ht' => $outstandingTotal, 'total_ttc' => $outstandingTotalIncTax, 'refs' => $arrayofref); // 'opened' is 'incl taxes'
4811
        } else {
4812
            return array();
4813
        }
4814
    }
4815
4816
    /**
4817
     *  Return amount of bill not yet paid and total of all invoices
4818
     *
4819
     *  @param     string   $mode       'customer' or 'supplier'
4820
     *  @param     int      $late       0 => all invoice, 1=> only late
4821
     *  @return    array                array('opened'=>Amount including tax that remains to pay, 'total_ht'=>Total amount without tax of all objects paid or not, 'total_ttc'=>Total amount including tax of all object paid or not)
4822
     */
4823
    public function getOutstandingBills($mode = 'customer', $late = 0)
4824
    {
4825
        $table = 'facture';
4826
        if ($mode == 'supplier') {
4827
            $table = 'facture_fourn';
4828
        }
4829
4830
        /* Accurate value of remain to pay is to sum remaintopay for each invoice
4831
         $paiement = $invoice->getSommePaiement();
4832
         $creditnotes=$invoice->getSumCreditNotesUsed();
4833
         $deposits=$invoice->getSumDepositsUsed();
4834
         $alreadypayed=price2num($paiement + $creditnotes + $deposits,'MT');
4835
         $remaintopay=price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits,'MT');
4836
         */
4837
        $sql = "SELECT rowid, ref, total_ht, total_ttc, paye, type, fk_statut as status, close_code FROM " . MAIN_DB_PREFIX . $table . " as f";
4838
        $sql .= " WHERE fk_soc = " . ((int) $this->id);
4839
        if (!empty($late)) {
4840
            $sql .= " AND date_lim_reglement < '" . $this->db->idate(dol_now()) . "'";
4841
        }
4842
        if ($mode == 'supplier') {
4843
            $sql .= " AND entity IN (" . getEntity('facture_fourn') . ")";
4844
        } else {
4845
            $sql .= " AND entity IN (" . getEntity('invoice') . ")";
4846
        }
4847
4848
        dol_syslog("getOutstandingBills", LOG_DEBUG);
4849
        $resql = $this->db->query($sql);
4850
        if ($resql) {
4851
            $outstandingOpened = 0;
4852
            $outstandingTotal = 0;
4853
            $outstandingTotalIncTax = 0;
4854
            $arrayofref = array();
4855
            $arrayofrefopened = array();
4856
            if ($mode == 'supplier') {
4857
                $tmpobject = new FactureFournisseur($this->db);
4858
            } else {
4859
                $tmpobject = new Facture($this->db);
4860
            }
4861
            while ($obj = $this->db->fetch_object($resql)) {
4862
                $arrayofref[$obj->rowid] = $obj->ref;
4863
                $tmpobject->id = $obj->rowid;
4864
4865
                if (
4866
                    $obj->status != $tmpobject::STATUS_DRAFT                                           // Not a draft
4867
                    && !($obj->status == $tmpobject::STATUS_ABANDONED && $obj->close_code == 'replaced')  // Not a replaced invoice
4868
                ) {
4869
                    $outstandingTotal += $obj->total_ht;
4870
                    $outstandingTotalIncTax += $obj->total_ttc;
4871
                }
4872
4873
                $remaintopay = 0;
4874
4875
                if (
4876
                    $obj->paye == 0
4877
                    && $obj->status != $tmpobject::STATUS_DRAFT         // Not a draft
4878
                    && $obj->status != $tmpobject::STATUS_ABANDONED     // Not abandoned
4879
                    && $obj->status != $tmpobject::STATUS_CLOSED
4880
                ) {     // Not classified as paid
4881
                    //$sql .= " AND (status <> 3 OR close_code <> 'abandon')";      // Not abandoned for undefined reason
4882
                    $paiement = $tmpobject->getSommePaiement();
4883
                    $creditnotes = $tmpobject->getSumCreditNotesUsed();
4884
                    $deposits = $tmpobject->getSumDepositsUsed();
4885
4886
                    $remaintopay = ($obj->total_ttc - $paiement - $creditnotes - $deposits);
4887
                    $outstandingOpened += $remaintopay;
4888
                }
4889
4890
                //if credit note is converted but not used
4891
                // TODO Do this also for customer ?
4892
                if ($mode == 'supplier' && $obj->type == FactureFournisseur::TYPE_CREDIT_NOTE && $tmpobject->isCreditNoteUsed()) {
0 ignored issues
show
Bug introduced by
The method isCreditNoteUsed() does not exist on Dolibarr\Code\Compta\Classes\Facture. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

4892
                if ($mode == 'supplier' && $obj->type == FactureFournisseur::TYPE_CREDIT_NOTE && $tmpobject->/** @scrutinizer ignore-call */ isCreditNoteUsed()) {
Loading history...
4893
                    $remainingcreditnote = $tmpobject->getSumFromThisCreditNotesNotUsed();
4894
                    $remaintopay -= $remainingcreditnote;
4895
                    $outstandingOpened -= $remainingcreditnote;
4896
                }
4897
4898
                if ($remaintopay) {
4899
                    $arrayofrefopened[$obj->rowid] = $obj->ref;
4900
                }
4901
            }
4902
            return array('opened' => $outstandingOpened, 'total_ht' => $outstandingTotal, 'total_ttc' => $outstandingTotalIncTax, 'refs' => $arrayofref, 'refsopened' => $arrayofrefopened); // 'opened' is 'incl taxes'
4903
        } else {
4904
            dol_syslog("Sql error " . $this->db->lasterror, LOG_ERR);
4905
            return array();
4906
        }
4907
    }
4908
4909
    /**
4910
     * Return label of status customer is prospect/customer
4911
     *
4912
     * @return   string         Label
4913
     * @see getTypeUrl()
4914
     */
4915
    public function getLibCustProspStatut()
4916
    {
4917
        return $this->LibCustProspStatut($this->client);
4918
    }
4919
4920
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
4921
    /**
4922
     *  Return the label of the customer/prospect status
4923
     *
4924
     *  @param  int     $status         Id of prospection status
4925
     *  @return string                  Label of prospection status
4926
     */
4927
    public function LibCustProspStatut($status)
4928
    {
4929
		// phpcs:enable
4930
        global $langs;
4931
        $langs->load('companies');
4932
4933
        if ($status == 0) {
4934
            return $langs->trans("NorProspectNorCustomer");
4935
        } elseif ($status == 1) {
4936
            return $langs->trans("Customer");
4937
        } elseif ($status == 2) {
4938
            return $langs->trans("Prospect");
4939
        } elseif ($status == 3) {
4940
            return $langs->trans("ProspectCustomer");
4941
        }
4942
4943
        return '';
4944
    }
4945
4946
4947
    /**
4948
     *  Create a document onto disk according to template module.
4949
     *
4950
     *  @param  string      $modele         Generator to use. Caller must set it to obj->model_pdf.
4951
     *  @param  Translate   $outputlangs    object lang a utiliser pour traduction
4952
     *  @param  int         $hidedetails    Hide details of lines
4953
     *  @param  int         $hidedesc       Hide description
4954
     *  @param  int         $hideref        Hide ref
4955
     *  @param  null|array  $moreparams     Array to provide more information
4956
     *  @return int                         Return integer <0 if KO, >0 if OK
4957
     */
4958
    public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
4959
    {
4960
        global $langs;
4961
4962
        if (!empty($moreparams) && !empty($moreparams['use_companybankid'])) {
4963
            $modelpath = "core/modules/bank/doc/";
4964
4965
            include_once DOL_DOCUMENT_ROOT . '/societe/class/companybankaccount.class.php';
4966
            $companybankaccount = new CompanyBankAccount($this->db);
4967
            $result = $companybankaccount->fetch($moreparams['use_companybankid']);
4968
            if (!$result) {
4969
                dol_print_error($this->db, $companybankaccount->error, $companybankaccount->errors);
4970
            }
4971
            $result = $companybankaccount->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
4972
            $this->last_main_doc = $companybankaccount->last_main_doc;
4973
        } else {
4974
            // Positionne le modele sur le nom du modele a utiliser
4975
            if (!dol_strlen($modele)) {
4976
                if (getDolGlobalString('COMPANY_ADDON_PDF')) {
4977
                    $modele = getDolGlobalString('COMPANY_ADDON_PDF');
4978
                } else {
4979
                    print $langs->trans("Error") . " " . $langs->trans("Error_COMPANY_ADDON_PDF_NotDefined");
4980
                    return 0;
4981
                }
4982
            }
4983
4984
            if (!isset($this->bank_account)) {
4985
                $bac = new CompanyBankAccount($this->db);
4986
                // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
4987
                $result = $bac->fetch(0, '', $this->id);
4988
                if ($result > 0) {
4989
                    $this->bank_account = $bac;
4990
                } else {
4991
                    $this->bank_account = '';
4992
                }
4993
            }
4994
4995
            $modelpath = "core/modules/societe/doc/";
4996
4997
            $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
4998
        }
4999
5000
        return $result;
5001
    }
5002
5003
5004
    /**
5005
     * Sets object to supplied categories.
5006
     *
5007
     * Deletes object from existing categories not supplied.
5008
     * Adds it to non existing supplied categories.
5009
     * Existing categories are left untouch.
5010
     *
5011
     * @param   int[]|int   $categories     Category ID or array of Categories IDs
5012
     * @param   string      $type_categ     Category type ('customer' or 'supplier')
5013
     * @return  int                         Return integer <0 if KO, >0 if OK
5014
     */
5015
    public function setCategories($categories, $type_categ)
5016
    {
5017
        // Decode type
5018
        if (!in_array($type_categ, array(Categorie::TYPE_CUSTOMER, Categorie::TYPE_SUPPLIER))) {
5019
            dol_syslog(__METHOD__ . ': Type ' . $type_categ . 'is an unknown company category type. Done nothing.', LOG_ERR);
5020
            return -1;
5021
        }
5022
5023
        return parent::setCategoriesCommon($categories, $type_categ);
5024
    }
5025
5026
    /**
5027
     * Sets sales representatives of the thirdparty
5028
     *
5029
     * @param   int[]|int   $salesrep       User ID or array of user IDs
5030
     * @param   bool        $onlyAdd        Only add (no delete before)
5031
     * @return  int                         Return integer <0 if KO, >0 if OK
5032
     */
5033
    public function setSalesRep($salesrep, $onlyAdd = false)
5034
    {
5035
        global $user;
5036
5037
        // Handle single user
5038
        if (!is_array($salesrep)) {
5039
            $salesrep = array($salesrep);
5040
        }
5041
5042
        $to_del = array(); // Nothing to delete
5043
        $to_add = $salesrep;
5044
        if ($onlyAdd === false) {
5045
            // Get current users
5046
            $existing = $this->getSalesRepresentatives($user, 1);
5047
5048
            // Diff
5049
            if (is_array($existing)) {
5050
                $to_del = array_diff($existing, $salesrep);
5051
                $to_add = array_diff($salesrep, $existing);
5052
            }
5053
        }
5054
5055
        $error = 0;
5056
5057
        // Process
5058
        foreach ($to_del as $del) {
5059
            $this->del_commercial($user, $del);
5060
        }
5061
        foreach ($to_add as $add) {
5062
            $result = $this->add_commercial($user, $add);
5063
            if ($result < 0) {
5064
                $error++;
5065
                break;
5066
            }
5067
        }
5068
5069
        return $error ? -1 : 1;
5070
    }
5071
5072
    /**
5073
     *    Define third-party type of current company
5074
     *
5075
     *    @param    int     $typent_id  third party type rowid in llx_c_typent
5076
     *    @return   int                 Return integer <0 if KO, >0 if OK
5077
     */
5078
    public function setThirdpartyType($typent_id)
5079
    {
5080
        global $user;
5081
5082
        dol_syslog(__METHOD__, LOG_DEBUG);
5083
5084
        if ($this->id) {
5085
            $result = $this->setValueFrom('fk_typent', $typent_id, '', null, '', '', $user, 'COMPANY_MODIFY');
5086
5087
            if ($result > 0) {
5088
                $this->typent_id = $typent_id;
5089
                $this->typent_code = dol_getIdFromCode($this->db, $this->typent_id, 'c_typent', 'id', 'code');
5090
                return 1;
5091
            } else {
5092
                return -1;
5093
            }
5094
        } else {
5095
            return -1;
5096
        }
5097
    }
5098
5099
    /**
5100
     * Function used to replace a thirdparty id with another one.
5101
     * It must be used within a transaction to avoid trouble
5102
     *
5103
     * @param   DoliDB  $dbs        Database handler, because function is static we name it $dbs not $db to avoid breaking coding test
5104
     * @param   int     $origin_id  Old thirdparty id (will be removed)
5105
     * @param   int     $dest_id    New thirdparty id
5106
     * @return  bool                True if success, False if error
5107
     */
5108
    public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
5109
    {
5110
        if ($origin_id == $dest_id) {
5111
            dol_syslog('Error: Try to merge a thirdparty into itself');
5112
            return false;
5113
        }
5114
5115
        // Sales representationves cannot be twice in the same thirdparties so we look for them and remove the one that are common some to avoid duplicate.
5116
        // Because this function is meant to be executed within a transaction, we won't take care of begin/commit.
5117
        $sql = 'SELECT rowid FROM ' . MAIN_DB_PREFIX . 'societe_commerciaux ';
5118
        $sql .= ' WHERE fk_soc = ' . (int) $dest_id . ' AND fk_user IN ( ';
5119
        $sql .= ' SELECT fk_user ';
5120
        $sql .= ' FROM ' . MAIN_DB_PREFIX . 'societe_commerciaux ';
5121
        $sql .= ' WHERE fk_soc = ' . (int) $origin_id . ') ';
5122
5123
        $resql = $dbs->query($sql);
5124
        while ($obj = $dbs->fetch_object($resql)) {
5125
            $dbs->query('DELETE FROM ' . MAIN_DB_PREFIX . 'societe_commerciaux WHERE rowid = ' . ((int) $obj->rowid));
5126
        }
5127
5128
        // llx_societe_extrafields table must not be here because we don't care about the old thirdparty extrafields that are managed directly into mergeCompany.
5129
        // Do not include llx_societe because it will be replaced later.
5130
        $tables = array(
5131
            'societe_account',
5132
            'societe_commerciaux',
5133
            'societe_prices',
5134
            'societe_remise',
5135
            'societe_remise_except',
5136
            'societe_rib'
5137
        );
5138
5139
        return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
5140
    }
5141
5142
    /**
5143
     * Sets an accountancy code for a thirdparty.
5144
     * Also calls COMPANY_MODIFY trigger when modified
5145
     *
5146
     * @param   string  $type   It can be only 'buy' or 'sell'
5147
     * @param   string  $value  Accountancy code
5148
     * @return  int             Return integer <0 KO >0 OK
5149
     */
5150
    public function setAccountancyCode($type, $value)
5151
    {
5152
        global $user, $langs, $conf;
5153
5154
        $this->db->begin();
5155
5156
        if ($type == 'buy') {
5157
            $field = 'accountancy_code_buy';
5158
        } elseif ($type == 'sell') {
5159
            $field = 'accountancy_code_sell';
5160
        } else {
5161
            return -1;
5162
        }
5163
5164
        $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element . " SET ";
5165
        $sql .= $field . " = '" . $this->db->escape($value) . "'";
5166
        $sql .= " WHERE rowid = " . ((int) $this->id);
5167
5168
        dol_syslog(get_class($this) . "::" . __FUNCTION__, LOG_DEBUG);
5169
        $resql = $this->db->query($sql);
5170
5171
        if ($resql) {
5172
            // Call triggers
5173
            include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
5174
            $interface = new Interfaces($this->db);
5175
            $result = $interface->run_triggers('COMPANY_MODIFY', $this, $user, $langs, $conf);
5176
            if ($result < 0) {
5177
                $this->errors = $interface->errors;
5178
                $this->db->rollback();
5179
                return -1;
5180
            }
5181
            // End call triggers
5182
5183
            $this->$field = $value;
5184
5185
            $this->db->commit();
5186
            return 1;
5187
        } else {
5188
            $this->error = $this->db->lasterror();
5189
            $this->db->rollback();
5190
            return -1;
5191
        }
5192
    }
5193
5194
    /**
5195
     *  Function to get partnerships array
5196
     *
5197
     *  @param      string      $mode       'member' or 'thirdparty'
5198
     *  @return     int                     Return integer <0 if KO, >0 if OK
5199
     */
5200
    public function fetchPartnerships($mode)
5201
    {
5202
        global $langs;
5203
5204
        $this->partnerships[] = array();
5205
5206
        return 1;
5207
    }
5208
5209
    /**
5210
     *  Return clicable link of object (with eventually picto)
5211
     *
5212
     *  @param      string      $option                 Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link)
5213
     *  @param      array       $arraydata              Array of data
5214
     *  @return     string                              HTML Code for Kanban thumb.
5215
     */
5216
    public function getKanbanView($option = '', $arraydata = array())
5217
    {
5218
        $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
5219
5220
        $return = '<div class="box-flex-item box-flex-grow-zero">';
5221
        $return .= '<div class="info-box info-box-sm">';
5222
        $return .= '<span class="info-box-icon bg-infobox-action">';
5223
        $return .= img_picto('', $this->picto);
5224
        $return .= '</span>';
5225
        $return .= '<div class="info-box-content">';
5226
        $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . (method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref) . '</span>';
5227
        if ($selected >= 0) {
5228
            $return .= '<input id="cb' . $this->id . '" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="' . $this->id . '"' . ($selected ? ' checked="checked"' : '') . '>';
5229
        }
5230
        if (property_exists($this, 'code_client')) {
5231
            $return .= '<br><span class="info-box-label opacitymedium">' . $this->code_client . '</span>';
5232
        }
5233
        if (method_exists($this, 'getLibStatut')) {
5234
            $return .= '<br><div class="info-box-status">' . $this->getLibStatut(3) . '</div>';
5235
        }
5236
        $return .= '</div>';
5237
        $return .= '</div>';
5238
        $return .= '</div>';
5239
5240
        return $return;
5241
    }
5242
5243
    /**
5244
     *    Get array of all contacts for a society (stored in societe_contacts instead of element_contacts for all other objects)
5245
     *
5246
     *    @param    int         $list       0:Return array contains all properties, 1:Return array contains just id
5247
     *    @param    string      $code       Filter on this code of contact type ('SHIPPING', 'BILLING', ...)
5248
     *    @param    string      $element    Filter on this element of default contact type ('facture', 'propal', 'commande' ...)
5249
     *    @return   array|int               Array of contacts, -1 if error
5250
     *
5251
     */
5252
    public function getContacts($list = 0, $code = '', $element = '')
5253
    {
5254
        // phpcs:enable
5255
        global $langs;
5256
5257
        $tab = array();
5258
5259
        $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
5260
        $sql .= ", t.fk_soc as socid, t.statut as statuscontact";
5261
        $sql .= ", t.civility as civility, t.lastname as lastname, t.firstname, t.email";
5262
        $sql .= ", tc.source, tc.element, tc.code, tc.libelle as type_label";
5263
        $sql .= " FROM " . $this->db->prefix() . "c_type_contact tc";
5264
        $sql .= ", " . $this->db->prefix() . "societe_contacts sc";
5265
        $sql .= " LEFT JOIN " . $this->db->prefix() . "socpeople t on sc.fk_socpeople = t.rowid";
5266
        $sql .= " WHERE sc.fk_soc = " . ((int) $this->id);
5267
        $sql .= " AND sc.fk_c_type_contact = tc.rowid";
5268
        if (!empty($element)) {
5269
            $sql .= " AND tc.element = '" . $this->db->escape($element) . "'";
5270
        }
5271
        if ($code) {
5272
            $sql .= " AND tc.code = '" . $this->db->escape($code) . "'";
5273
        }
5274
        $sql .= " AND sc.entity IN (" . getEntity($this->element) . ")";
5275
        $sql .= " AND tc.source = 'external'";
5276
        $sql .= " AND tc.active = 1";
5277
5278
        $sql .= " ORDER BY t.lastname ASC";
5279
5280
        dol_syslog(get_class($this) . "::getContacts", LOG_DEBUG);
5281
        $resql = $this->db->query($sql);
5282
        if ($resql) {
5283
            $num = $this->db->num_rows($resql);
5284
            $i = 0;
5285
            while ($i < $num) {
5286
                $obj = $this->db->fetch_object($resql);
5287
5288
                if (!$list) {
5289
                    $transkey = "TypeContact_" . $obj->element . "_" . $obj->source . "_" . $obj->code;
5290
                    $libelle_type = ($langs->trans($transkey) != $transkey ? $langs->trans($transkey) : $obj->type_label);
5291
                    $tab[$i] = array(
5292
                        'source' => $obj->source,
5293
                        'socid' => $obj->socid,
5294
                        'id' => $obj->id,
5295
                        'nom' => $obj->lastname, // For backward compatibility
5296
                        'civility' => $obj->civility,
5297
                        'lastname' => $obj->lastname,
5298
                        'firstname' => $obj->firstname,
5299
                        'email' => $obj->email,
5300
                        'login' => (empty($obj->login) ? '' : $obj->login),
5301
                        'photo' => (empty($obj->photo) ? '' : $obj->photo),
5302
                        'statuscontact' => $obj->statuscontact,
5303
                        'rowid' => $obj->rowid,
5304
                        'code' => $obj->code,
5305
                        'element' => $obj->element,
5306
                        'libelle' => $libelle_type,
5307
                        'status' => $obj->statuslink,
5308
                        'fk_c_type_contact' => $obj->fk_c_type_contact
5309
                    );
5310
                } else {
5311
                    $tab[$i] = $obj->id;
5312
                }
5313
5314
                $i++;
5315
            }
5316
5317
            return $tab;
5318
        } else {
5319
            $this->error = $this->db->lasterror();
5320
            dol_print_error($this->db);
5321
            return -1;
5322
        }
5323
    }
5324
5325
    /**
5326
     *    Merge a company with current one, deleting the given company $soc_origin_id.
5327
     *    The company given in parameter will be removed.
5328
     *    This is called for example by the societe/card.php file.
5329
     *    It calls the method replaceThirdparty() of each object with relation with thirdparties,
5330
     *    including hook 'replaceThirdparty' for external modules.
5331
     *
5332
     *    @param    int     $soc_origin_id      Company to merge the data from
5333
     *    @return   int                         -1 if error, >=0 if OK
5334
     */
5335
    public function mergeCompany($soc_origin_id)
5336
    {
5337
        global $conf, $langs, $hookmanager, $user, $action;
5338
5339
        $error = 0;
5340
        $soc_origin = new Societe($this->db);       // The thirdparty that we will delete
5341
5342
        dol_syslog("mergeCompany merge thirdparty id=" . $soc_origin_id . " (will be deleted) into the thirdparty id=" . $this->id);
5343
5344
        if (!$error && $soc_origin->fetch($soc_origin_id) < 1) {
5345
            $this->error = $langs->trans('ErrorRecordNotFound');
5346
            $error++;
5347
        }
5348
5349
        if (!$error) {
5350
            $this->db->begin();
5351
5352
            // Recopy some data
5353
            $this->client |= $soc_origin->client;
5354
            $this->fournisseur |= $soc_origin->fournisseur;
5355
            $listofproperties = array(
5356
                'address', 'zip', 'town', 'state_id', 'country_id', 'phone', 'phone_mobile', 'fax', 'email', 'socialnetworks', 'url', 'barcode',
5357
                'idprof1', 'idprof2', 'idprof3', 'idprof4', 'idprof5', 'idprof6',
5358
                'tva_intra', 'effectif_id', 'forme_juridique', 'remise_percent', 'remise_supplier_percent', 'mode_reglement_supplier_id', 'cond_reglement_supplier_id', 'name_bis',
5359
                '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',
5360
                'code_client', 'code_fournisseur', 'code_compta', 'code_compta_fournisseur',
5361
                'model_pdf', 'webservices_url', 'webservices_key', 'accountancy_code_sell', 'accountancy_code_buy', 'typent_id'
5362
            );
5363
            foreach ($listofproperties as $property) {
5364
                if (empty($this->$property)) {
5365
                    $this->$property = $soc_origin->$property;
5366
                }
5367
            }
5368
5369
            if ($this->typent_id == -1) {
5370
                $this->typent_id = $soc_origin->typent_id;
5371
            }
5372
5373
            // Concat some data
5374
            $listofproperties = array(
5375
                'note_public', 'note_private'
5376
            );
5377
            foreach ($listofproperties as $property) {
5378
                $this->$property = dol_concatdesc($this->$property, $soc_origin->$property);
5379
            }
5380
5381
            // Merge extrafields
5382
            if (is_array($soc_origin->array_options)) {
5383
                foreach ($soc_origin->array_options as $key => $val) {
5384
                    if (empty($this->array_options[$key])) {
5385
                        $this->array_options[$key] = $val;
5386
                    }
5387
                }
5388
            }
5389
5390
            // If alias name is not defined on target thirdparty, we can store in it the old name of company.
5391
            if (empty($this->name_bis) && $this->name != $soc_origin->name) {
5392
                $this->name_bis = $this->name;
5393
            }
5394
5395
            // Merge categories
5396
            $static_cat = new Categorie($this->db);
5397
5398
            $custcats_ori = $static_cat->containing($soc_origin->id, 'customer', 'id');
5399
            $custcats = $static_cat->containing($this->id, 'customer', 'id');
5400
            $custcats = array_merge($custcats, $custcats_ori);
5401
            $this->setCategories($custcats, 'customer');
5402
5403
            $suppcats_ori = $static_cat->containing($soc_origin->id, 'supplier', 'id');
5404
            $suppcats = $static_cat->containing($this->id, 'supplier', 'id');
5405
            $suppcats = array_merge($suppcats, $suppcats_ori);
5406
            $this->setCategories($suppcats, 'supplier');
5407
5408
            // If thirdparty has a new code that is same than origin, we clean origin code to avoid duplicate key from database unique keys.
5409
            if (
5410
                $soc_origin->code_client == $this->code_client
5411
                || $soc_origin->code_fournisseur == $this->code_fournisseur
5412
                || $soc_origin->barcode == $this->barcode
5413
            ) {
5414
                dol_syslog("We clean customer and supplier code so we will be able to make the update of target");
5415
                $soc_origin->code_client = '';
5416
                $soc_origin->code_fournisseur = '';
5417
                $soc_origin->barcode = '';
5418
                $soc_origin->update($soc_origin->id, $user, 0, 1, 1, 'merge');
5419
            }
5420
5421
            // Update
5422
            $result = $this->update($this->id, $user, 0, 1, 1, 'merge');
5423
5424
            if ($result < 0) {
5425
                $error++;
5426
            }
5427
5428
            // Move links
5429
            if (!$error) {
5430
                $objects = array(
5431
                    'Adherent' => '/adherents/class/adherent.class.php',
5432
                    //'Categorie' => '/categories/class/categorie.class.php',   // Already processed previously
5433
                    'ActionComm' => '/comm/action/class/actioncomm.class.php',
5434
                    'Propal' => '/comm/propal/class/propal.class.php',
5435
                    'Commande' => '/commande/class/commande.class.php',
5436
                    'Facture' => '/compta/facture/class/facture.class.php',
5437
                    'FactureRec' => '/compta/facture/class/facture-rec.class.php',
5438
                    'LignePrelevement' => '/compta/prelevement/class/ligneprelevement.class.php',
5439
                    'Contact' => '/contact/class/contact.class.php',
5440
                    'Contrat' => '/contrat/class/contrat.class.php',
5441
                    'Expedition' => '/expedition/class/expedition.class.php',
5442
                    'CommandeFournisseur' => '/fourn/class/fournisseur.commande.class.php',
5443
                    'FactureFournisseur' => '/fourn/class/fournisseur.facture.class.php',
5444
                    'FactureFournisseurRec' => '/fourn/class/fournisseur.facture-rec.class.php',
5445
                    'Reception' => '/reception/class/reception.class.php',
5446
                    'SupplierProposal' => '/supplier_proposal/class/supplier_proposal.class.php',
5447
                    'ProductFournisseur' => '/fourn/class/fournisseur.product.class.php',
5448
                    'Product' => '/product/class/product.class.php',
5449
                    //'ProductThirparty' => '...',  // for llx_product_thirdparty
5450
                    'Project' => '/projet/class/project.class.php',
5451
                    'User' => '/user/class/user.class.php',
5452
                    'Account' => '/compta/bank/class/account.class.php',
5453
                    'ConferenceOrBoothAttendee' => '/eventorganization/class/conferenceorboothattendee.class.php',
5454
                    'Societe' => '/societe/class/societe.class.php',
5455
                    //'SocieteAccount', 'SocietePrice', 'SocieteRib',... are processed into the replaceThirparty of Societe.
5456
                );
5457
                if ($this->db->DDLListTables($conf->db->name, $this->db->prefix() . 'delivery')) {
5458
                    $objects['Delivery'] = '/delivery/class/delivery.class.php';
5459
                }
5460
                if ($this->db->DDLListTables($conf->db->name, $this->db->prefix() . 'mrp_mo')) {
5461
                    $objects['Mo'] = '/mrp/class/mo.class.php';
5462
                }
5463
                if ($this->db->DDLListTables($conf->db->name, $this->db->prefix() . 'don')) {
5464
                    $objects['Don'] = '/don/class/don.class.php';
5465
                }
5466
                if ($this->db->DDLListTables($conf->db->name, $this->db->prefix() . 'partnership')) {
5467
                    $objects['PartnerShip'] = '/partnership/class/partnership.class.php';
5468
                }
5469
                if ($this->db->DDLListTables($conf->db->name, $this->db->prefix() . 'fichinter')) {
5470
                    $objects['Fichinter'] = '/fichinter/class/fichinter.class.php';
5471
                }
5472
                if ($this->db->DDLListTables($conf->db->name, $this->db->prefix() . 'ticket')) {
5473
                    $objects['Ticket'] = '/ticket/class/ticket.class.php';
5474
                }
5475
5476
                //First, all core objects must update their tables
5477
                foreach ($objects as $object_name => $object_file) {
5478
                    if (is_array($object_file)) {
5479
                        if (empty($object_file['enabled'])) {
5480
                            continue;
5481
                        }
5482
                        $object_file = $object_file['file'];
5483
                    }
5484
5485
                    require_once DOL_DOCUMENT_ROOT . $object_file;
5486
5487
                    if (!$error && !$object_name::replaceThirdparty($this->db, $soc_origin->id, $this->id)) {
5488
                        $error++;
5489
                        $this->error = $this->db->lasterror();
5490
                        break;
5491
                    }
5492
                }
5493
            }
5494
5495
            // External modules should update their ones too
5496
            if (!$error) {
5497
                $parameters = array('soc_origin' => $soc_origin->id, 'soc_dest' => $this->id);
5498
                $reshook = $hookmanager->executeHooks('replaceThirdparty', $parameters, $this, $action);
5499
5500
                if ($reshook < 0) {
5501
                    $this->error = $hookmanager->error;
5502
                    $this->errors = $hookmanager->errors;
5503
                    $error++;
5504
                }
5505
            }
5506
5507
5508
            if (!$error) {
5509
                $this->context = array('merge' => 1, 'mergefromid' => $soc_origin->id, 'mergefromname' => $soc_origin->name);
5510
5511
                // Call trigger
5512
                $result = $this->call_trigger('COMPANY_MODIFY', $user);
5513
                if ($result < 0) {
5514
                    $error++;
5515
                }
5516
                // End call triggers
5517
            }
5518
5519
            if (!$error) {
5520
                // Move files from the dir of the third party to delete into the dir of the third party to keep
5521
                if (!empty($conf->societe->multidir_output[$this->entity])) {
5522
                    $srcdir = $conf->societe->multidir_output[$this->entity] . "/" . $soc_origin->id;
5523
                    $destdir = $conf->societe->multidir_output[$this->entity] . "/" . $this->id;
5524
5525
                    if (dol_is_dir($srcdir)) {
5526
                        $dirlist = dol_dir_list($srcdir, 'files', 1);
5527
                        foreach ($dirlist as $filetomove) {
5528
                            $destfile = $destdir . '/' . $filetomove['relativename'];
5529
                            //var_dump('Move file '.$filetomove['relativename'].' into '.$destfile);
5530
                            dol_move($filetomove['fullname'], $destfile, '0', 0, 0, 1);
5531
                        }
5532
                        //exit;
5533
                    }
5534
                }
5535
            }
5536
5537
5538
            if (!$error) {
5539
                // We finally remove the old thirdparty
5540
                if ($soc_origin->delete($soc_origin->id, $user) < 1) {
5541
                    $this->error = $soc_origin->error;
5542
                    $this->errors = $soc_origin->errors;
5543
                    $error++;
5544
                }
5545
            }
5546
5547
            if (!$error) {
5548
                $this->db->commit();
5549
                return 0;
5550
            } else {
5551
                $langs->load("errors");
5552
                $this->error = $langs->trans('ErrorsThirdpartyMerge');
5553
                $this->db->rollback();
5554
                return -1;
5555
            }
5556
        }
5557
5558
        return -1;
5559
    }
5560
}
5561