Test Failed
Branch main (a69845)
by Rafael
63:42
created

FactureFournisseurLigneRec   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 263
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 172
dl 0
loc 263
rs 10
c 0
b 0
f 0
wmc 24

3 Methods

Rating   Name   Duplication   Size   Complexity  
B delete() 0 40 9
D update() 0 75 13
B fetch() 0 68 2
1
<?php
2
3
/* Copyright (C) 2003-2005  Rodolphe Quiedeville    <[email protected]>
4
 * Copyright (C) 2004-2019	Laurent Destailleur		<[email protected]>
5
 * Copyright (C) 2009-2012	Regis Houssin			    <[email protected]>
6
 * Copyright (C) 2010-2011	Juanjo Menent			    <[email protected]>
7
 * Copyright (C) 2012       Cedric Salvador       <[email protected]>
8
 * Copyright (C) 2013       Florian Henry		  	  <[email protected]>
9
 * Copyright (C) 2015       Marcos García         <[email protected]>
10
 * Copyright (C) 2017-2024  Frédéric France       <[email protected]>
11
 * Copyright (C) 2024		    MDW							      <[email protected]>
12
 * Copyright (C) 2023-2024  Nick Fragoulis
13
 * Copyright (C) 2024       Rafael San José             <[email protected]>
14
 *
15
 * This program is free software; you can redistribute it and/or modify
16
 * it under the terms of the GNU General Public License as published by
17
 * the Free Software Foundation; either version 3 of the License, or
18
 * (at your option) any later version.
19
 *
20
 * This program is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 * GNU General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU General Public License
26
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
27
 */
28
29
/**
30
 *  \file       htdocs/fourn/facture/class/fournisseur.facture-rec.class.php
31
 *  \ingroup    invoice
32
 *  \brief      File for class to manage invoice templates
33
 */
34
35
require_once constant('DOL_DOCUMENT_ROOT') . '/core/class/notify.class.php';
36
require_once constant('DOL_DOCUMENT_ROOT') . '/product/class/product.class.php';
37
require_once constant('DOL_DOCUMENT_ROOT') . '/fourn/class/fournisseur.facture.class.php';
38
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/date.lib.php';
39
40
41
/**
42
 *  Class to manage invoice templates
43
 */
44
class FactureFournisseurRec extends CommonInvoice
45
{
46
    const TRIGGER_PREFIX = 'SUPPLIERBILLREC';
47
    /**
48
     * @var string ID to identify managed object
49
     */
50
    public $element = 'invoice_supplier_rec';
51
52
    /**
53
     * @var string Name of table without prefix where object is stored
54
     */
55
    public $table_element = 'facture_fourn_rec';
56
57
    /**
58
     * @var string    Name of subtable line
59
     */
60
    public $table_element_line = 'facture_fourn_det_rec';
61
62
    /**
63
     * @var string Field with ID of parent key if this field has a parent
64
     */
65
    public $fk_element = 'fk_facture_fourn';
66
67
    /**
68
     * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
69
     */
70
    public $picto = 'bill';
71
72
    /**
73
     * {@inheritdoc}
74
     */
75
    protected $table_ref_field = 'titre';
76
77
    /**
78
     * @var string  The label of recurring invoice
79
     * @deprecated  Use $title
80
     */
81
    public $titre;
82
    /**
83
     * @var string The label of recurring invoice
84
     */
85
    public $title;
86
87
    public $ref_supplier;
88
    public $socid;
89
90
    /**
91
     * @var int
92
     * @deprecated
93
     */
94
    public $fk_soc;
95
96
    public $suspended; // status
97
98
    /**
99
     * @var string      Label of invoice
100
     * @deprecated      Use $label
101
     */
102
    public $libelle;
103
    /**
104
     * @var string      Label of invoice
105
     */
106
    public $label;
107
108
    /**
109
     * @var double $amount
110
     * @deprecated
111
     */
112
    public $amount;
113
    /**
114
     * @var double $remise
115
     * @deprecated
116
     */
117
    public $remise;
118
119
    public $vat_src_code;
120
    public $localtax1;
121
    public $localtax2;
122
123
    public $user_author;
124
    public $user_modif;
125
    public $fk_project;
126
127
    public $mode_reglement_id;
128
    public $mode_reglement_code;
129
    public $cond_reglement_code;
130
    public $cond_reglement_doc;
131
    public $cond_reglement_id;
132
133
    /**
134
     * @var int Deadline for payment
135
     */
136
    public $date_lim_reglement;
137
138
    public $usenewprice = 0;
139
    public $frequency;
140
    public $unit_frequency;
141
    public $date_when;
142
    public $date_last_gen;
143
144
    /**
145
     * @var int nb generation done
146
     */
147
    public $nb_gen_done;
148
149
    /**
150
     * @var int nb generation max
151
     */
152
    public $nb_gen_max;
153
154
    /**
155
     * @var int<0,1> auto validate 0 to create in draft, 1 to create and validate the new invoice
156
     */
157
    public $auto_validate; //
158
    public $generate_pdf; // 1 to generate PDF on invoice generation (default)
159
160
    /**
161
     * Invoice lines
162
     * @var CommonInvoiceLine[]
163
     */
164
    public $lines = array();
165
166
167
    /* Override fields in CommonObject
168
    public $entity;
169
    public $date_creation;
170
    public $date_modification;
171
    public $total_ht;
172
    public $total_tva;
173
    public $total_ttc;
174
    public $fk_account;
175
    public $mode_reglement;
176
    public $cond_reglement;
177
    public $note_public;
178
    public $note_private;
179
    */
180
181
    /**
182
     *  'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password')
183
     *         Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)"
184
     *  'label' the translation key.
185
     *  'enabled' is a condition when the field must be managed.
186
     *  'position' is the sort order of field.
187
     *  'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0).
188
     *  '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)
189
     *  'noteditable' says if field is not editable (1 or 0)
190
     *  '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.
191
     *  'index' if we want an index in database.
192
     *  'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommended to name the field fk_...).
193
     *  'searchall' is 1 if we want to search in this field when making a search from the quick search button.
194
     *  '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).
195
     *  'css' is the CSS style to use on field. For example: 'maxwidth200'
196
     *  'help' is a string visible as a tooltip on field
197
     *  'showoncombobox' if value of the field must be visible into the label of the combobox that list record
198
     *  '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.
199
     *  'arrayofkeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel")
200
     *  'comment' is not used. You can store here any text of your choice. It is not used by application.
201
     *
202
     *  Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor.
203
     */
204
205
    // BEGIN MODULEBUILDER PROPERTIES
206
    /**
207
     * @var array<string,array{type:string,label:string,enabled:int<0,2>|string,position:int,notnull?:int,visible:int,noteditable?:int,default?:string,index?:int,foreignkey?:string,searchall?:int,isameasure?:int,css?:string,csslist?:string,help?:string,showoncombobox?:int,disabled?:int,arrayofkeyval?:array<int,string>,comment?:string}>  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 16 could not be parsed: Expected '}' at position 16, but found 'int'.
Loading history...
208
     */
209
    public $fields = array(
210
        'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
211
        'titre' => array('type' => 'varchar(100)', 'label' => 'Titre', 'enabled' => 1, 'showoncombobox' => 1, 'visible' => -1, 'position' => 15),
212
        'ref_supplier' => array('type' => 'varchar(180)', 'label' => 'RefSupplier', 'enabled' => 1, 'showoncombobox' => 1, 'visible' => -1, 'position' => 20),
213
        'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 25, 'index' => 1),
214
        'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php', 'label' => 'ThirdParty', 'enabled' => 'isModEnabled("societe")', 'visible' => -1, 'notnull' => 1, 'position' => 30),
215
        'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 35),
216
        'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 40),
217
        'suspended' => array('type' => 'integer', 'label' => 'Suspended', 'enabled' => 1, 'visible' => -1, 'position' => 225),
218
        'libelle' => array('type' => 'varchar(100)', 'label' => 'Libelle', 'enabled' => 1, 'showoncombobox' => 0, 'visible' => -1, 'position' => 15),
219
220
        'localtax1' => array('type' => 'double(24,8)', 'label' => 'Localtax1', 'enabled' => 1, 'visible' => -1, 'position' => 60, 'isameasure' => 1),
221
        'localtax2' => array('type' => 'double(24,8)', 'label' => 'Localtax2', 'enabled' => 1, 'visible' => -1, 'position' => 65, 'isameasure' => 1),
222
        'total_ht' => array('type' => 'double(24,8)', 'label' => 'Total', 'enabled' => 1, 'visible' => -1, 'position' => 70, 'isameasure' => 1),
223
        'total_tva' => array('type' => 'double(24,8)', 'label' => 'Tva', 'enabled' => 1, 'visible' => -1, 'position' => 55, 'isameasure' => 1),
224
        'total_ttc' => array('type' => 'double(24,8)', 'label' => 'Total ttc', 'enabled' => 1, 'visible' => -1, 'position' => 75, 'isameasure' => 1),
225
226
        'fk_user_author' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user author', 'enabled' => 1, 'visible' => -1, 'position' => 80),
227
        'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'position' => 210),
228
        'fk_projet' => array('type' => 'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label' => 'Fk projet', 'enabled' => "isModEnabled('project')", 'visible' => -1, 'position' => 85),
229
        'fk_account' => array('type' => 'integer', 'label' => 'Fk account', 'enabled' => 'isModEnabled("bank")', 'visible' => -1, 'position' => 175),
230
        'fk_cond_reglement' => array('type' => 'integer', 'label' => 'Fk cond reglement', 'enabled' => 1, 'visible' => -1, 'position' => 90),
231
        'fk_mode_reglement' => array('type' => 'integer', 'label' => 'Fk mode reglement', 'enabled' => 1, 'visible' => -1, 'position' => 95),
232
        'date_lim_reglement' => array('type' => 'date', 'label' => 'Date lim reglement', 'enabled' => 1, 'visible' => -1, 'position' => 100),
233
234
        'note_private' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 105),
235
        'note_public' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 110),
236
        'modelpdf' => array('type' => 'varchar(255)', 'label' => 'Modelpdf', 'enabled' => 1, 'visible' => -1, 'position' => 115),
237
238
        'fk_multicurrency' => array('type' => 'integer', 'label' => 'Fk multicurrency', 'enabled' => 1, 'visible' => -1, 'position' => 180),
239
        'multicurrency_code' => array('type' => 'varchar(255)', 'label' => 'Multicurrency code', 'enabled' => 1, 'visible' => -1, 'position' => 185),
240
        'multicurrency_tx' => array('type' => 'double(24,8)', 'label' => 'Multicurrency tx', 'enabled' => 1, 'visible' => -1, 'position' => 190, 'isameasure' => 1),
241
        'multicurrency_total_ht' => array('type' => 'double(24,8)', 'label' => 'Multicurrency total ht', 'enabled' => 1, 'visible' => -1, 'position' => 195, 'isameasure' => 1),
242
        'multicurrency_total_tva' => array('type' => 'double(24,8)', 'label' => 'Multicurrency total tva', 'enabled' => 1, 'visible' => -1, 'position' => 200, 'isameasure' => 1),
243
        'multicurrency_total_ttc' => array('type' => 'double(24,8)', 'label' => 'Multicurrency total ttc', 'enabled' => 1, 'visible' => -1, 'position' => 205, 'isameasure' => 1),
244
245
        'usenewprice' => array('type' => 'integer', 'label' => 'UseNewPrice', 'enabled' => 1, 'visible' => 0, 'position' => 155),
246
        'frequency' => array('type' => 'integer', 'label' => 'Frequency', 'enabled' => 1, 'visible' => -1, 'position' => 150),
247
        'unit_frequency' => array('type' => 'varchar(2)', 'label' => 'Unit frequency', 'enabled' => 1, 'visible' => -1, 'position' => 125),
248
249
        'date_when' => array('type' => 'datetime', 'label' => 'Date when', 'enabled' => 1, 'visible' => -1, 'position' => 130),
250
        'date_last_gen' => array('type' => 'datetime', 'label' => 'Date last gen', 'enabled' => 1, 'visible' => -1, 'position' => 135),
251
        'nb_gen_done' => array('type' => 'integer', 'label' => 'Nb gen done', 'enabled' => 1, 'visible' => -1, 'position' => 140),
252
        'nb_gen_max' => array('type' => 'integer', 'label' => 'Nb gen max', 'enabled' => 1, 'visible' => -1, 'position' => 145),
253
        'revenuestamp' => array('type' => 'double(24,8)', 'label' => 'RevenueStamp', 'enabled' => 1, 'visible' => -1, 'position' => 160, 'isameasure' => 1),
254
        'auto_validate' => array('type' => 'integer', 'label' => 'Auto validate', 'enabled' => 1, 'visible' => -1, 'position' => 165),
255
        'generate_pdf' => array('type' => 'integer', 'label' => 'Generate pdf', 'enabled' => 1, 'visible' => -1, 'position' => 170),
256
    );
257
    // END MODULEBUILDER PROPERTIES
258
259
    const STATUS_NOTSUSPENDED = 0;
260
    const STATUS_SUSPENDED = 1;
261
262
263
264
    /**
265
     *  Constructor
266
     *
267
     *  @param      DoliDB      $db     Database handler
268
     */
269
    public function __construct($db)
270
    {
271
        $this->db = $db;
272
    }
273
274
    /**
275
     *    Create a predefined supplier invoice
276
     *
277
     * @param   User    $user           User object
278
     * @param   int     $facFournId     Id invoice
279
     * @param   int     $notrigger      No trigger
280
     * @return  int                     Return integer <0 if KO, id of invoice created if OK
281
     */
282
    public function create($user, $facFournId, $notrigger = 0)
283
    {
284
        global $conf;
285
286
        $error = 0;
287
        $now = dol_now();
288
289
        // Clean parameters
290
        $this->titre = empty($this->titre) ? '' : $this->titre; // deprecated
0 ignored issues
show
Deprecated Code introduced by
The property FactureFournisseurRec::$titre has been deprecated: Use $title ( Ignorable by Annotation )

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

290
        $this->titre = empty(/** @scrutinizer ignore-deprecated */ $this->titre) ? '' : $this->titre; // 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...
291
        $this->title = empty($this->title) ? '' : $this->title;
292
        $keyforref = $this->table_ref_field;
293
        $this->ref = $this->$keyforref;
294
        $this->ref_supplier = empty($this->ref_supplier) ? '' : $this->ref_supplier;
295
        $this->usenewprice = empty($this->usenewprice) ? 0 : $this->usenewprice;
296
        $this->suspended = empty($this->suspended) ? 0 : $this->suspended;
297
        // No frequency defined then no next date to execution
298
        if (empty($this->frequency)) {
299
            $this->frequency = 0;
300
            $this->date_when = null;
301
        }
302
        $this->frequency = abs($this->frequency);
303
        $this->nb_gen_done = 0;
304
        $this->nb_gen_max = empty($this->nb_gen_max) ? 0 : $this->nb_gen_max;
305
        $this->auto_validate = empty($this->auto_validate) ? 0 : $this->auto_validate;
306
        $this->generate_pdf = empty($this->generate_pdf) ? 0 : $this->generate_pdf;
307
308
        $this->db->begin();
309
310
        // On charge la facture fournisseur depuis laquelle on crée la facture fournisseur modèle
311
        $facfourn_src = new FactureFournisseur($this->db);
312
        $result = $facfourn_src->fetch($facFournId);
313
        if ($result > 0) {
314
            $sql = 'INSERT INTO ' . MAIN_DB_PREFIX . 'facture_fourn_rec (';
315
            $sql .= 'titre';
316
            $sql .= ", subtype";
317
            $sql .= ', ref_supplier';
318
            $sql .= ', entity';
319
            $sql .= ', fk_soc';
320
            $sql .= ', datec';
321
            $sql .= ', suspended';
322
            $sql .= ', libelle';
323
            $sql .= ', total_ttc';
324
            $sql .= ', fk_user_author';
325
            $sql .= ', fk_projet';
326
            $sql .= ', fk_account';
327
            $sql .= ', fk_cond_reglement';
328
            $sql .= ', fk_mode_reglement';
329
            $sql .= ', date_lim_reglement';
330
            $sql .= ', note_private';
331
            $sql .= ', note_public';
332
            $sql .= ', modelpdf';
333
            $sql .= ', fk_multicurrency';
334
            $sql .= ', multicurrency_code';
335
            $sql .= ', multicurrency_tx';
336
            $sql .= ', usenewprice';
337
            $sql .= ', frequency';
338
            $sql .= ', unit_frequency';
339
            $sql .= ', date_when';
340
            $sql .= ', date_last_gen';
341
            $sql .= ', nb_gen_done';
342
            $sql .= ', nb_gen_max';
343
            $sql .= ', auto_validate';
344
            $sql .= ', generate_pdf';
345
            $sql .= ') VALUES (';
346
            $sql .= "'" . $this->db->escape($this->title) . "'";
347
            $sql .= ", " . ($this->subtype ? "'" . $this->db->escape($this->subtype) . "'" : "null");
348
            $sql .= ", '" . $this->db->escape($this->ref_supplier) . "'";
349
            $sql .= ", " . ((int) $conf->entity);
350
            $sql .= ", " . ((int) $facfourn_src->socid);
351
            $sql .= ", '" . $this->db->idate($now) . "'";
352
            $sql .= ", " . ((int) $this->suspended);
353
            $sql .= ", '" . $this->db->escape($this->libelle) . "'";
0 ignored issues
show
Deprecated Code introduced by
The property FactureFournisseurRec::$libelle has been deprecated: Use $label ( Ignorable by Annotation )

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

353
            $sql .= ", '" . $this->db->escape(/** @scrutinizer ignore-deprecated */ $this->libelle) . "'";

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...
354
            $sql .= ", " . (!empty($facfourn_src->total_ttc) ? (float) $facfourn_src->total_ttc : '0');                              // amount
355
            $sql .= ", " . ((int) $user->id);
356
            $sql .= ", " . (!empty($this->fk_project) ? ((int) $this->fk_project) : 'NULL');
357
            $sql .= ", " . (!empty($facfourn_src->fk_account) ? ((int) $facfourn_src->fk_account) : 'NULL');
358
            $sql .= ", " . ($this->cond_reglement_id > 0 ? (int) $this->cond_reglement_id : 'NULL');
359
            $sql .= ", " . ($this->mode_reglement_id > 0 ? (int) $this->mode_reglement_id : 'NULL');
360
            $sql .= ", " . ($facfourn_src->date_echeance > 0 ? "'" . $this->db->idate($facfourn_src->date_echeance) . "'" : 'NULL');      // date_lim_reglement
361
            $sql .= ", " . (!empty($this->note_private) ? "'" . $this->db->escape($this->note_private) . "'" : 'NULL');
362
            $sql .= ", " . (!empty($this->note_public) ? "'" . $this->db->escape($this->note_public) . "'" : 'NULL');
363
            $sql .= ", " . (!empty($this->model_pdf) ? "'" . $this->db->escape($this->model_pdf) . "'" : 'NULL');
364
            $sql .= ", " . (int) $facfourn_src->fk_multicurrency;
365
            $sql .= ", '" . $this->db->escape($facfourn_src->multicurrency_code) . "'";
366
            $sql .= ", " . (float) $facfourn_src->multicurrency_tx;
367
            $sql .= ", " . (int) $this->usenewprice;
368
            $sql .= ", " . (int) $this->frequency;
369
            $sql .= ", '" . $this->db->escape($this->unit_frequency) . "'";
370
            $sql .= ", " . (!empty($this->date_when) ? "'" . $this->db->idate($this->date_when) . "'" : 'NULL');
371
            $sql .= ", " . (!empty($this->date_last_gen) ? "'" . $this->db->idate($this->date_last_gen) . "'" : 'NULL');
372
            $sql .= ", " . (int) $this->nb_gen_done;
373
            $sql .= ", " . (int) $this->nb_gen_max;
374
            $sql .= ", " . (int) $this->auto_validate;
375
            $sql .= ", " . (int) $this->generate_pdf;
376
            $sql .= ')';
377
378
            if ($this->db->query($sql)) {
379
                $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . 'facture_fourn_rec');
380
381
                // Fields used into addline later
382
                $this->fk_multicurrency = $facfourn_src->fk_multicurrency;
383
384
                $this->multicurrency_code = $facfourn_src->multicurrency_code;
385
                $this->multicurrency_tx = $facfourn_src->multicurrency_tx;
386
387
                // Add lines
388
                $num = count($facfourn_src->lines);
389
                for ($i = 0; $i < $num; $i++) {
390
                    $tva_tx = $facfourn_src->lines[$i]->tva_tx;
391
                    if (!empty($facfourn_src->lines[$i]->vat_src_code) && !preg_match('/\(/', (string) $tva_tx)) {
392
                        $tva_tx .= ' (' . $facfourn_src->lines[$i]->vat_src_code . ')';
393
                    }
394
395
                    $result_insert = $this->addline(
396
                        $facfourn_src->lines[$i]->fk_product,
397
                        $facfourn_src->lines[$i]->ref_supplier,
0 ignored issues
show
Bug Best Practice introduced by
The property ref_supplier does not exist on CommonInvoiceLine. Since you implemented __get, consider adding a @property annotation.
Loading history...
398
                        $facfourn_src->lines[$i]->product_label,
399
                        $facfourn_src->lines[$i]->desc ? $facfourn_src->lines[$i]->desc : $facfourn_src->lines[$i]->description,
400
                        $facfourn_src->lines[$i]->pu_ht,
0 ignored issues
show
Bug Best Practice introduced by
The property pu_ht does not exist on CommonInvoiceLine. Since you implemented __get, consider adding a @property annotation.
Loading history...
401
                        $facfourn_src->lines[$i]->pu_ttc,
402
                        $facfourn_src->lines[$i]->qty,
403
                        $facfourn_src->lines[$i]->remise_percent,
404
                        $tva_tx,
405
                        $facfourn_src->lines[$i]->localtax1_tx,
406
                        $facfourn_src->lines[$i]->localtax2_tx,
407
                        'HT',
408
                        $facfourn_src->lines[$i]->product_type,
409
                        $facfourn_src->lines[$i]->date_start,
0 ignored issues
show
Bug Best Practice introduced by
The property date_start does not exist on CommonInvoiceLine. Since you implemented __get, consider adding a @property annotation.
Loading history...
410
                        $facfourn_src->lines[$i]->date_end,
0 ignored issues
show
Bug Best Practice introduced by
The property date_end does not exist on CommonInvoiceLine. Since you implemented __get, consider adding a @property annotation.
Loading history...
411
                        $facfourn_src->lines[$i]->info_bits,
412
                        $facfourn_src->lines[$i]->special_code,
413
                        $facfourn_src->lines[$i]->rang,
0 ignored issues
show
Bug Best Practice introduced by
The property rang does not exist on CommonInvoiceLine. Since you implemented __get, consider adding a @property annotation.
Loading history...
414
                        $facfourn_src->lines[$i]->fk_unit
415
                    );
416
417
                    if ($result_insert < 0) {
418
                        $error++;
419
                    } else {
420
                        $objectline = new FactureFournisseurLigneRec($this->db);
421
422
                        $result2 = $objectline->fetch($result_insert);
423
                        if ($result2 > 0) {
424
                            // Extrafields
425
                            if (method_exists($facfourn_src->lines[$i], 'fetch_optionals')) {
426
                                $facfourn_src->lines[$i]->fetch_optionals($facfourn_src->lines[$i]->id);
427
                                $objectline->array_options = $facfourn_src->lines[$i]->array_options;
428
                            }
429
430
                            $result = $objectline->insertExtraFields();
431
                            if ($result < 0) {
432
                                $error++;
433
                            }
434
                        } elseif ($result2 < 0) {
435
                            $this->errors[] = $objectline->error;
436
                            $error++;
437
                        }
438
                    }
439
                }
440
441
                if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) {  // To use new linkedObjectsIds instead of old linked_objects
442
                    $this->linked_objects = $this->linkedObjectsIds; // TODO Replace linked_objects with linkedObjectsIds
443
                }
444
445
                // Add object linked
446
                if (!$error && $this->id && !empty($this->linked_objects) && is_array($this->linked_objects)) {
447
                    foreach ($this->linked_objects as $origin => $tmp_origin_id) {
448
                        if (is_array($tmp_origin_id)) {       // New behaviour, if linked_object can have several links per type, so is something like array('contract'=>array(id1, id2, ...))
449
                            foreach ($tmp_origin_id as $origin_id) {
450
                                $ret = $this->add_object_linked($origin, $origin_id);
451
                                if (!$ret) {
452
                                    $this->error = $this->db->lasterror();
453
                                    $error++;
454
                                }
455
                            }
456
                        } else { // Old behaviour, if linked_object has only one link per type, so is something like array('contract'=>id1))
457
                            $origin_id = $tmp_origin_id;
458
                            $ret = $this->add_object_linked($origin, $origin_id);
459
                            if (!$ret) {
460
                                $this->error = $this->db->lasterror();
461
                                $error++;
462
                            }
463
                        }
464
                    }
465
                }
466
467
                if (!$error) {
468
                    $result = $this->insertExtraFields();
469
                    if ($result < 0) {
470
                        $error++;
471
                    }
472
                }
473
474
                if (!$error && !$notrigger) {
475
                    // Call trigger
476
                    $result = $this->call_trigger('SUPPLIERBILLREC_CREATE', $user);
477
                    if ($result < 0) {
478
                        $this->db->rollback();
479
                        return -2;
480
                    }
481
                    // End call triggers
482
                }
483
484
                if ($error) {
485
                    $this->db->rollback();
486
                    return -3;
487
                } else {
488
                    $this->db->commit();
489
                    return $this->id;
490
                }
491
            } else {
492
                $this->error = $this->db->lasterror();
493
                $this->db->rollback();
494
                return -2;
495
            }
496
        } else {
497
            $this->db->rollback();
498
            return -1;
499
        }
500
    }
501
502
503
    /**
504
     *  Update fourn_invoice_rec.
505
     *
506
     *  @param      User    $user                   User
507
     *  @param      int     $notrigger              No trigger
508
     *  @return     int                             Return integer <0 if KO, Id of line if OK
509
     */
510
    public function update(User $user, $notrigger = 0)
511
    {
512
        $error = 0;
513
514
        $sql = "UPDATE " . MAIN_DB_PREFIX . "facture_fourn_rec SET";
515
        $sql .= " titre = '" . (!empty($this->title) ? $this->db->escape($this->title) : "") . "'," ;
516
        $sql .= " subtype=" . (isset($this->subtype) ? $this->db->escape($this->subtype) : "null") . ",";
517
        $sql .= " ref_supplier = '" . (!empty($this->ref_supplier) ? $this->db->escape($this->ref_supplier) : "") . "',";
518
        $sql .= " entity = " . (!empty($this->entity) ? ((int) $this->entity) : 1) . ',';
519
        if (!empty($this->socid) && $this->socid > 0) {
520
            $sql .= " fk_soc = " . ((int) $this->socid) . ',';
521
        } elseif (!empty($this->fk_soc) && $this->fk_soc > 0) { // For backward compatibility
522
            $sql .= " fk_soc = " . ((int) $this->fk_soc) . ',';
523
        }
524
        $sql .= " suspended = " . (!empty($this->suspended) ? ((int) $this->suspended) : 0) . ',';
525
        $sql .= " libelle = " . (!empty($this->libelle) ? "'" . $this->db->escape($this->libelle) . "'" : 'NULL') . ",";
0 ignored issues
show
Deprecated Code introduced by
The property FactureFournisseurRec::$libelle has been deprecated: Use $label ( Ignorable by Annotation )

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

525
        $sql .= " libelle = " . (!empty(/** @scrutinizer ignore-deprecated */ $this->libelle) ? "'" . $this->db->escape($this->libelle) . "'" : 'NULL') . ",";

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...
526
        $sql .= " vat_src_code = " . (!empty($this->vat_src_code) ? "'" . $this->db->escape($this->vat_src_code) . "'" : 'NULL') . ',';
527
        $sql .= " localtax1 = " . (!empty($this->localtax1) ? ((float) $this->localtax1) : 0.00) . ',';
528
        $sql .= " localtax2 = " . (!empty($this->localtax2) ? ((float) $this->localtax2) : 0.00) . ',';
529
        $sql .= " total_ht = " . (!empty($this->total_ht) ? ((float) $this->total_ht) : 0.00) . ',';
530
        $sql .= " total_tva = " . (!empty($this->total_tva) ? ((float) $this->total_tva) : 0.00) . ',';
531
        $sql .= " total_ttc = " . (!empty($this->total_ttc) ? ((float) $this->total_ttc) : 0.00) . ',';
532
        $sql .= " fk_user_modif = " . ((int) $user->id) . ',';
533
        $sql .= " fk_projet = " . (!empty($this->fk_project) ? ((int) $this->fk_project) : 'NULL') . ',';
534
        $sql .= " fk_account = " . (!empty($this->fk_account) ? ((int) $this->fk_account) : 'NULL') . ',';
535
        $sql .= " fk_mode_reglement = " . (!empty($this->mode_reglement_id) ? ((int) $this->mode_reglement_id) : 'NULL') . ',';
536
        $sql .= " fk_cond_reglement = " . (!empty($this->cond_reglement_id) ? ((int) $this->cond_reglement_id) : 'NULL') . ',';
537
        $sql .= " date_lim_reglement = " . (!empty($this->date_lim_reglement) ? "'" . $this->db->idate($this->date_lim_reglement) . "'" : 'NULL') . ',';
538
        $sql .= " note_private = '" . (!empty($this->note_private) ? $this->db->escape($this->note_private) : '') . "',";
539
        $sql .= " note_public = '" . (!empty($this->note_public) ? $this->db->escape($this->note_public) : '') . "',";
540
        $sql .= " modelpdf = " . (!empty($this->model_pdf) ? "'" . $this->db->escape($this->model_pdf) . "'" : 'NULL') . ",";
541
        $sql .= " fk_multicurrency = " . (!empty($this->fk_multicurrency) ? ((int) $this->fk_multicurrency) : 'NULL') . ',';
542
        $sql .= " multicurrency_code = " . (!empty($this->multicurrency_code) ? "'" . $this->db->escape($this->multicurrency_code) . "'" : 'NULL') . ",";
543
        $sql .= " multicurrency_tx = " . (!empty($this->multicurrency_tx) ? ((float) $this->multicurrency_tx) : 1) . ',';
544
        $sql .= " multicurrency_total_ht = " . (!empty($this->multicurrency_total_ht) ? ((float) $this->multicurrency_total_ht) : 0.00) . ',';
545
        $sql .= " multicurrency_total_tva = " . (!empty($this->multicurrency_total_tva) ? ((float) $this->multicurrency_total_tva) : 0.00) . ',';
546
        $sql .= " multicurrency_total_ttc = " . (!empty($this->multicurrency_total_ttc) ? ((float) $this->multicurrency_total_ttc) : 0.00) . ',';
547
        $sql .= " usenewprice = " . (!empty($this->usenewprice) ? ((int) $this->usenewprice) : 0) . ',';
548
        $sql .= " frequency = " . (!empty($this->frequency) ? ((int) $this->frequency) : 0) . ',';
549
        $sql .= " unit_frequency = '" . (!empty($this->unit_frequency) ? $this->db->escape($this->unit_frequency) : '') . "',";
550
        $sql .= " date_when = " . (!empty($this->date_when) ? "'" . $this->db->idate($this->date_when) . "'" : 'NULL') . ',';
551
        $sql .= " date_last_gen = " . (!empty($this->date_last_gen) ? "'" . $this->db->idate($this->date_last_gen) . "'" : 'NULL') . ',';
552
        $sql .= " nb_gen_done = " . (!empty($this->nb_gen_done) ? ((int) $this->nb_gen_done) : 0) . ',';
553
        $sql .= " nb_gen_max = " . (!empty($this->nb_gen_max) ? ((int) $this->nb_gen_max) : 0) . ',';
554
        $sql .= " auto_validate = " . (!empty($this->auto_validate) ? ((int) $this->auto_validate) : 0);
555
        $sql .= " WHERE rowid = " . (int) $this->id;
556
557
        $this->db->begin();
558
559
        dol_syslog(get_class($this) . "::update", LOG_DEBUG);
560
        $resql = $this->db->query($sql);
561
        if ($resql) {
562
            if (!$error) {
563
                $result = $this->insertExtraFields();
564
                if ($result < 0) {
565
                    $error++;
566
                }
567
            }
568
569
            if (!$error && !$notrigger) {
570
                // Call trigger
571
                $result = $this->call_trigger('SUPPLIERBILLREC_MODIFY', $user);
572
                if ($result < 0) {
573
                    $this->db->rollback();
574
                    return -2;
575
                }
576
                // End call triggers
577
            }
578
            $this->db->commit();
579
            return 1;
580
        } else {
581
            $this->error = $this->db->lasterror();
582
            $this->db->rollback();
583
            return -2;
584
        }
585
    }
586
587
    /**
588
     *  Load object and lines
589
     *
590
     *  @param      int     $rowid          Id of object to load
591
     *  @param      string  $ref            Reference of recurring invoice
592
     *  @param      string  $ref_ext        External reference of invoice
593
     *  @return     int                     >0 if OK, <0 if KO, 0 if not found
594
     */
595
    public function fetch($rowid, $ref = '', $ref_ext = '')
596
    {
597
        $sql = 'SELECT f.rowid, f.titre as title, f.subtype, f.ref_supplier, f.entity, f.fk_soc';
598
        $sql .= ', f.datec, f.tms, f.suspended';
599
        $sql .= ', f.libelle as label';
600
        $sql .= ', f.vat_src_code, f.localtax1, f.localtax2';
601
        $sql .= ', f.total_tva, f.total_ht, f.total_ttc';
602
        $sql .= ', f.fk_user_author, f.fk_user_modif';
603
        $sql .= ', f.fk_projet as fk_project, f.fk_account';
604
        $sql .= ', f.fk_mode_reglement, p.code as mode_reglement_code, p.libelle as mode_reglement_libelle';
605
        $sql .= ', f.fk_cond_reglement, c.code as cond_reglement_code, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_doc';
606
        $sql .= ', f.date_lim_reglement';
607
        $sql .= ', f.note_private, f.note_public, f.modelpdf as model_pdf';
608
        $sql .= ', f.fk_multicurrency, f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc';
609
        $sql .= ', f.usenewprice, f.frequency, f.unit_frequency, f.date_when, f.date_last_gen, f.nb_gen_done, f.nb_gen_max, f.auto_validate';
610
        $sql .= ', f.generate_pdf';
611
        $sql .= ' FROM ' . MAIN_DB_PREFIX . 'facture_fourn_rec as f';
612
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_payment_term as c ON f.fk_cond_reglement = c.rowid';
613
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_paiement as p ON f.fk_mode_reglement = p.id';
614
        $sql .= ' WHERE f.entity IN (' . getEntity('invoice') . ')';
615
        if ($rowid) {
616
            $sql .= ' AND f.rowid=' . (int) $rowid;
617
        } elseif ($ref) {
618
            $sql .= " AND f.titre='" . $this->db->escape($ref) . "'";
619
        } else {
620
            $sql .= ' AND f.rowid = 0';
621
        }
622
623
        $result = $this->db->query($sql);
624
        if ($result) {
625
            if ($this->db->num_rows($result)) {
626
                $obj = $this->db->fetch_object($result);
627
628
                $keyforref = $this->table_ref_field;
629
630
                $this->id                       = $obj->rowid;
631
                $this->titre                    = $obj->title;
0 ignored issues
show
Deprecated Code introduced by
The property FactureFournisseurRec::$titre has been deprecated: Use $title ( Ignorable by Annotation )

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

631
                /** @scrutinizer ignore-deprecated */ $this->titre                    = $obj->title;

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...
632
                $this->title                    = $obj->title;
633
                $this->subtype                        = $obj->subtype;
634
                $this->ref                      = $obj->title;
635
                $this->ref_supplier             = $obj->ref_supplier;
636
                $this->entity                   = $obj->entity;
637
                $this->socid                    = $obj->fk_soc;
638
                $this->date_creation            = $obj->datec;
639
                $this->date_modification        = $obj->tms;
640
                $this->suspended                = $obj->suspended;
641
                $this->libelle                  = $obj->label;
0 ignored issues
show
Deprecated Code introduced by
The property FactureFournisseurRec::$libelle has been deprecated: Use $label ( Ignorable by Annotation )

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

641
                /** @scrutinizer ignore-deprecated */ $this->libelle                  = $obj->label;

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...
642
                $this->label                    = $obj->label;
643
                $this->vat_src_code             = $obj->vat_src_code;
644
                $this->total_localtax1          = $obj->localtax1;
645
                $this->total_localtax2          = $obj->localtax2;
646
                $this->total_ht                 = $obj->total_ht;
647
                $this->total_tva                = $obj->total_tva;
648
                $this->total_ttc                = $obj->total_ttc;
649
                $this->user_author              = $obj->fk_user_author;
650
                $this->user_modif               = $obj->fk_user_modif;
651
                $this->fk_project               = $obj->fk_project;
652
                $this->fk_account               = $obj->fk_account;
653
                $this->mode_reglement_id        = $obj->fk_mode_reglement;
654
                $this->mode_reglement_code      = $obj->mode_reglement_code;
655
                $this->mode_reglement           = $obj->mode_reglement_libelle;
656
                $this->cond_reglement_id        = $obj->fk_cond_reglement;
657
                $this->cond_reglement_code      = $obj->cond_reglement_code;
658
                $this->cond_reglement           = $obj->cond_reglement_libelle;
0 ignored issues
show
Bug Best Practice introduced by
The property $cond_reglement is declared private in CommonObject. Since you implement __set, consider adding a @property or @property-write.
Loading history...
Deprecated Code introduced by
The property CommonObject::$cond_reglement has been deprecated: Use $cond_reglement_id instead - Kept for compatibility ( Ignorable by Annotation )

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

658
                /** @scrutinizer ignore-deprecated */ $this->cond_reglement           = $obj->cond_reglement_libelle;

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...
659
                $this->cond_reglement_doc       = $obj->cond_reglement_libelle_doc;
660
                $this->date_lim_reglement       = $this->db->jdate($obj->date_lim_reglement);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->db->jdate($obj->date_lim_reglement) can also be of type string. However, the property $date_lim_reglement 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...
661
                $this->note_private             = $obj->note_private;
662
                $this->note_public              = $obj->note_public;
663
                $this->model_pdf                = $obj->model_pdf;
664
665
                // Multicurrency
666
                $this->fk_multicurrency         = $obj->fk_multicurrency;
667
                $this->multicurrency_code       = $obj->multicurrency_code;
668
                $this->multicurrency_tx         = $obj->multicurrency_tx;
669
                $this->multicurrency_total_ht   = $obj->multicurrency_total_ht;
670
                $this->multicurrency_total_tva  = $obj->multicurrency_total_tva;
671
                $this->multicurrency_total_ttc  = $obj->multicurrency_total_ttc;
672
673
                $this->usenewprice              = $obj->usenewprice;
674
                $this->frequency                = $obj->frequency;
675
                $this->unit_frequency           = $obj->unit_frequency;
676
                $this->date_when                = $this->db->jdate($obj->date_when);
677
                $this->date_last_gen            = $this->db->jdate($obj->date_last_gen);
678
                $this->nb_gen_done              = $obj->nb_gen_done;
679
                $this->nb_gen_max               = $obj->nb_gen_max;
680
                $this->auto_validate            = $obj->auto_validate;
681
                $this->generate_pdf             = $obj->generate_pdf;
682
683
                // Retrieve all extrafield
684
                // fetch optionals attributes and labels
685
                $this->fetch_optionals();
686
687
                /*
688
                 * Lines
689
                 */
690
                $result = $this->fetch_lines();
691
                if ($result < 0) {
692
                    $this->error = $this->db->lasterror();
693
                    return -3;
694
                }
695
                return 1;
696
            } else {
697
                $this->error = 'Bill with id ' . $rowid . ' or ref ' . $ref . ' not found';
698
                dol_syslog('Facture::Fetch Error ' . $this->error, LOG_ERR);
699
                return -2;
700
            }
701
        } else {
702
            $this->error = $this->db->error();
703
            return -1;
704
        }
705
    }
706
707
708
    /**
709
     *  Create an array of invoice lines
710
     *
711
     *  @return int     >0 if OK, <0 if KO
712
     */
713
    public function getLinesArray()
714
    {
715
        return $this->fetch_lines();
716
    }
717
718
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
719
    /**
720
     *  Get lines of template invoices into this->lines
721
     *
722
     *  @return     int         1 if OK, < 0 if KO
723
     */
724
    public function fetch_lines()
725
    {
726
		// phpcs:enable
727
        $this->lines = array();
728
729
        // Retrieve all extrafield for line
730
        // fetch optionals attributes and labels
731
        /*if (!is_object($extrafields)) {
732
            require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
733
            $extrafields = new ExtraFields($this->db);
734
        }
735
        $extrafields->fetch_name_optionals_label($this->table_element_line, true);
736
        */
737
738
        $sql = 'SELECT l.rowid,';
739
        $sql .= ' l.fk_facture_fourn, l.fk_parent_line, l.fk_product, l.ref, l.label, l.description as line_desc,';
740
        $sql .= ' l.pu_ht, l.pu_ttc, l.qty, l.remise_percent, l.fk_remise_except, l.vat_src_code, l.tva_tx,';
741
        $sql .= ' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type,';
742
        $sql .= ' l.total_ht, l.total_tva, l.total_ttc, total_localtax1, total_localtax2,';
743
        $sql .= ' l.product_type, l.date_start, l.date_end,';
744
        $sql .= ' l.info_bits, l.special_code, l.rang,';
745
        $sql .= ' l.fk_unit, l.import_key, l.fk_user_author, l.fk_user_modif,';
746
        $sql .= ' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
747
        $sql .= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
748
        $sql .= ' FROM ' . MAIN_DB_PREFIX . 'facture_fourn_det_rec as l';
749
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'product as p ON l.fk_product = p.rowid';
750
        $sql .= ' WHERE l.fk_facture_fourn = ' . (int) $this->id;
751
        $sql .= ' ORDER BY l.rang';
752
753
        dol_syslog('FactureFournisseurRec::fetch_lines', LOG_DEBUG);
754
755
        $result = $this->db->query($sql);
756
        if ($result) {
757
            $num = $this->db->num_rows($result);
758
            $i = 0;
759
            while ($i < $num) {
760
                $objp = $this->db->fetch_object($result);
761
762
                $line = new FactureFournisseurLigneRec($this->db);
763
764
                $line->id                       = $objp->rowid;
765
                $line->fk_facture_fourn         = $objp->fk_facture_fourn;
766
                $line->fk_parent                = $objp->fk_parent_line;
767
                $line->fk_product               = $objp->fk_product;
768
                $line->ref_supplier             = $objp->ref;
769
                $line->label                    = $objp->label;
770
                $line->description              = $objp->line_desc;
0 ignored issues
show
Deprecated Code introduced by
The property FactureFournisseurLigneRec::$description has been deprecated: Use desc ( Ignorable by Annotation )

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

770
                /** @scrutinizer ignore-deprecated */ $line->description              = $objp->line_desc;

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...
771
                $line->desc                     = $objp->line_desc;
772
                $line->pu_ht                    = $objp->pu_ht;
773
                $line->pu_ttc                   = $objp->pu_ttc;
774
                $line->qty                      = $objp->qty;
775
                $line->remise_percent           = $objp->remise_percent;
776
                $line->fk_remise_except         = $objp->fk_remise_except;
777
                $line->vat_src_code             = $objp->vat_src_code;
778
                $line->tva_tx                   = $objp->tva_tx;
779
                $line->localtax1_tx             = $objp->localtax1_tx;
780
                $line->localtax1_type           = $objp->localtax1_type;
781
                $line->localtax2_tx             = $objp->localtax2_tx;
782
                $line->localtax2_type           = $objp->localtax2_type;
783
                $line->total_ht                 = $objp->total_ht;
784
                $line->total_tva                = $objp->total_tva;
785
                $line->total_localtax1          = $objp->total_localtax1;
786
                $line->total_localtax2          = $objp->total_localtax2;
787
                $line->total_ttc                = $objp->total_ttc;
788
                $line->product_type             = $objp->product_type;
789
                $line->date_start               = $objp->date_start;
790
                $line->date_end                 = $objp->date_end;
791
                $line->info_bits                = $objp->info_bits  ;
792
                $line->special_code             = $objp->special_code;
793
                $line->rang                     = $objp->rang;
794
                $line->fk_unit                  = $objp->fk_unit;
795
                $line->import_key               = $objp->import_key;
796
                $line->fk_user_author           = $objp->fk_user_author;
797
                $line->fk_user_modif            = $objp->fk_user_modif;
798
                $line->fk_multicurrency         = $objp->fk_multicurrency;
799
                $line->multicurrency_code       = $objp->multicurrency_code;
800
                $line->multicurrency_subprice   = $objp->multicurrency_subprice;
801
                $line->multicurrency_total_ht   = $objp->multicurrency_total_ht;
802
                $line->multicurrency_total_tva  = $objp->multicurrency_total_tva;
803
                $line->multicurrency_total_ttc  = $objp->multicurrency_total_ttc;
804
805
                $line->fetch_optionals();
806
807
                $this->lines[$i] = $line;
808
809
                $i++;
810
            }
811
812
            $this->db->free($result);
813
            return 1;
814
        } else {
815
            $this->error = $this->db->lasterror();
816
            return -3;
817
        }
818
    }
819
820
821
    /**
822
     *  Delete template invoice
823
     *
824
     *  @param      User    $user           User that delete.
825
     *  @param      int     $notrigger      1=Does not execute triggers, 0= execute triggers
826
     *  @param      int     $idwarehouse    Id warehouse to use for stock change.
827
     *  @return     int                     Return integer <0 if KO, >0 if OK
828
     */
829
    public function delete(User $user, $notrigger = 0, $idwarehouse = -1)
830
    {
831
        $rowid = $this->id;
832
833
        dol_syslog(get_class($this) . "::delete rowid=" . ((int) $rowid), LOG_DEBUG);
834
835
        $error = 0;
836
        $this->db->begin();
837
838
        $main = MAIN_DB_PREFIX . 'facture_fourn_det_rec';
839
        $ef = $main . "_extrafields";
840
841
        $sqlef = "DELETE FROM " . $ef . " WHERE fk_object IN (SELECT rowid FROM " . $main . " WHERE fk_facture_fourn = " . (int) $rowid . ")";
842
        $sql = "DELETE FROM " . MAIN_DB_PREFIX . "facture_fourn_det_rec WHERE fk_facture_fourn = " . (int) $rowid;
843
844
        if ($this->db->query($sqlef) && $this->db->query($sql)) {
845
            $sql = "DELETE FROM " . MAIN_DB_PREFIX . "facture_fourn_rec WHERE rowid = " . (int) $rowid;
846
            dol_syslog($sql);
847
            if ($this->db->query($sql)) {
848
                // Delete linked object
849
                $res = $this->deleteObjectLinked();
850
                if ($res < 0) {
851
                    $error = -3;
852
                }
853
                // Delete extrafields
854
                $res = $this->deleteExtraFields();
855
                if ($res < 0) {
856
                    $error = -4;
857
                }
858
            } else {
859
                $this->error = $this->db->lasterror();
860
                $error = -1;
861
            }
862
        } else {
863
            $this->error = $this->db->lasterror();
864
            $error = -2;
865
        }
866
        if (!$error && !$notrigger) {
867
            // Call trigger
868
            $result = $this->call_trigger('SUPPLIERBILLREC_DELETE', $user);
869
            if ($result < 0) {
870
                $error++;
871
            }
872
            // End call triggers
873
        }
874
        if (! $error) {
875
            $this->db->commit();
876
            return 1;
877
        } else {
878
            $this->db->rollback();
879
            return $error;
880
        }
881
    }
882
883
    /**
884
     * Add a line to recursive supplier invoice
885
     *
886
     * @param int       $fk_product     Product/Service ID predefined
887
     * @param string    $ref            Ref
888
     * @param string    $label          Label
889
     * @param string    $desc           Description de la ligne
890
     * @param double    $pu_ht          Unit price
891
     * @param double    $pu_ttc         Unit price with tax
892
     * @param double    $qty            Quantity
893
     * @param int       $remise_percent Percentage discount of the line
894
     * @param double    $txtva          Taux de tva force, sinon -1
895
     * @param int       $txlocaltax1    Local tax 1 rate (deprecated)
896
     * @param int       $txlocaltax2    Local tax 2 rate (deprecated)
897
     * @param string    $price_base_type HT or TTC
898
     * @param int       $type           Type of line (0=product, 1=service)
899
     * @param int       $date_start     Date start
900
     * @param int       $date_end       Date end
901
     * @param int       $info_bits      VAT npr or not ?
902
     * @param int       $special_code   Special code
903
     * @param int       $rang           Position of line
904
     * @param string    $fk_unit        Unit
905
     * @param int       $pu_ht_devise   Unit price in currency
906
     * @return int                      Return integer <0 if KO, Id of line if OK
907
     * @throws Exception
908
     */
909
    public function addline($fk_product, $ref, $label, $desc, $pu_ht, $pu_ttc, $qty, $remise_percent, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $price_base_type = 'HT', $type = 0, $date_start = 0, $date_end = 0, $info_bits = 0, $special_code = 0, $rang = -1, $fk_unit = null, $pu_ht_devise = 0)
910
    {
911
        global $mysoc, $user;
912
913
        include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php';
914
915
        $facid = $this->id; //Supplier invoice template ID linked to
916
917
        dol_syslog(get_class($this) . "::addline facid=$facid,desc=$desc,pu_ht=$pu_ht,qty=$qty,txtva=$txtva,txlocaltax1=$txlocaltax1,txlocaltax2=$txlocaltax2,fk_product=$fk_product,remise_percent=$remise_percent,info_bits=$info_bits,price_base_type=$price_base_type,pu_ttc=$pu_ttc,type=$type,fk_unit=$fk_unit,pu_ht_devise=$pu_ht_devise,date_start_fill=$date_start,date_end_fill=$date_end", LOG_DEBUG);
918
919
        // Check if object of the line is product or service
920
        if ($type < 0) {
921
            return -1;
922
        }
923
924
        if ($this->suspended == self::STATUS_NOTSUSPENDED) {
925
            $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc);
926
927
            // Clean vat code
928
            $reg = array();
929
            $vat_src_code = '';
930
            if (preg_match('/\((.*)\)/', (string) $txtva, $reg)) {
931
                $vat_src_code = $reg[1];
932
                $txtva = preg_replace('/\s*\(.*\)/', '', (string) $txtva); // Remove code into vatrate.
933
            }
934
935
            // Clean parameters
936
            $fk_product = empty($fk_product) ? 0 : $fk_product;
937
            $label = empty($label) ? '' : $label;
938
            $remise_percent = empty($remise_percent) ? 0 : price2num($remise_percent);
939
            $qty = price2num($qty);
940
            $pu_ht = price2num($pu_ht);
941
            $pu_ttc = price2num($pu_ttc);
942
            if (!preg_match('/\((.*)\)/', $txtva)) {
943
                $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5'
944
            }
945
            $txlocaltax1 = price2num($txlocaltax1);
946
            $txlocaltax2 = price2num($txlocaltax2);
947
            $txtva = !empty($txtva) ? $txtva : 0;
948
            $txlocaltax1 = !empty($txlocaltax1) ? $txlocaltax1 : 0;
949
            $txlocaltax2 = !empty($txlocaltax2) ? $txlocaltax2 : 0;
950
            $info_bits = !empty($info_bits) ? $info_bits : 0;
951
            $info_bits = !empty($info_bits) ? $info_bits : 0;
952
            $pu = $price_base_type == 'HT' ? $pu_ht : $pu_ttc;
953
954
            // Calcul du total TTC et de la TVA pour la ligne a partir de qty, pu, remise_percent et txtva
955
            // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
956
            // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
957
958
            $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise);
959
            $total_ht  = $tabprice[0];
960
            $total_tva = $tabprice[1];
961
            $total_ttc = $tabprice[2];
962
            $total_localtax1 = $tabprice[9];
963
            $total_localtax2 = $tabprice[10];
964
            $pu_ht = $tabprice[3];
965
966
            // MultiCurrency
967
            $multicurrency_total_ht  = $tabprice[16];
968
            $multicurrency_total_tva = $tabprice[17];
969
            $multicurrency_total_ttc = $tabprice[18];
970
            $pu_ht_devise = $tabprice[19];
971
972
            $this->db->begin();
973
            $product_type = $type;
974
            if ($fk_product) {
975
                $product = new Product($this->db);
976
                $result = $product->fetch($fk_product);
977
                if ($result < 0) {
978
                    return -1;
979
                }
980
                $product_type = $product->type;
981
                if (empty($label)) {
982
                    $label = $product->label;
983
                }
984
            }
985
986
            $sql = 'INSERT INTO ' . MAIN_DB_PREFIX . 'facture_fourn_det_rec (';
987
            $sql .= 'fk_facture_fourn';
988
            $sql .= ', fk_product';
989
            $sql .= ', ref';
990
            $sql .= ', label';
991
            $sql .= ', description';
992
            $sql .= ', pu_ht';
993
            $sql .= ', pu_ttc';
994
            $sql .= ', qty';
995
            $sql .= ', remise_percent';
996
            $sql .= ', fk_remise_except';
997
            $sql .= ', vat_src_code';
998
            $sql .= ', tva_tx';
999
            $sql .= ', localtax1_tx';
1000
            $sql .= ', localtax1_type';
1001
            $sql .= ', localtax2_tx';
1002
            $sql .= ', localtax2_type';
1003
            $sql .= ', total_ht';
1004
            $sql .= ', total_tva';
1005
            $sql .= ', total_localtax1';
1006
            $sql .= ', total_localtax2';
1007
            $sql .= ', total_ttc';
1008
            $sql .= ', product_type';
1009
            $sql .= ', date_start';
1010
            $sql .= ', date_end';
1011
            $sql .= ', info_bits';
1012
            $sql .= ', special_code';
1013
            $sql .= ', rang';
1014
            $sql .= ', fk_unit';
1015
            $sql .= ', fk_user_author';
1016
            $sql .= ', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc';
1017
            $sql .= ') VALUES (';
1018
            $sql .= ' ' . (int) $facid;   // source supplier invoice id
1019
            $sql .= ', ' . (!empty($fk_product) ? "'" . $this->db->escape($fk_product) . "'" : 'null');
1020
            $sql .= ', ' . (!empty($ref) ? "'" . $this->db->escape($ref) . "'" : 'null');
1021
            $sql .= ', ' . (!empty($label) ? "'" . $this->db->escape($label) . "'" : 'null');
1022
            $sql .= ", '" . $this->db->escape($desc) . "'";
1023
            $sql .= ', ' . price2num($pu_ht);
1024
            $sql .= ', ' . price2num($pu_ttc);
1025
            $sql .= ', ' . price2num($qty);
1026
            $sql .= ', ' . price2num($remise_percent);
1027
            $sql .= ', null';
1028
            $sql .= ", '" . $this->db->escape($vat_src_code) . "'";
1029
            $sql .= ', ' . price2num($txtva);
1030
            $sql .= ', ' . price2num($txlocaltax1);
1031
            $sql .= ", '" . $this->db->escape(isset($localtaxes_type[0]) ? $localtaxes_type[0] : '') . "'";
1032
            $sql .= ', ' . price2num($txlocaltax2);
1033
            $sql .= ", '" . $this->db->escape(isset($localtaxes_type[2]) ? $localtaxes_type[2] : '') . "'";
1034
            $sql .= ', ' . price2num($total_ht);
1035
            $sql .= ', ' . price2num($total_tva);
1036
            $sql .= ', ' . price2num($total_localtax1);
1037
            $sql .= ', ' . price2num($total_localtax2);
1038
            $sql .= ', ' . price2num($total_ttc);
1039
            $sql .= ', ' . (int) $product_type;
1040
            $sql .= ', ' . ($date_start > 0 ? (int) $date_start : 'NULL');
1041
            $sql .= ', ' . ($date_end > 0 ? (int) $date_end : 'NULL');
1042
            $sql .= ', ' . (int) $info_bits;
1043
            $sql .= ', ' . (int) $special_code;
1044
            $sql .= ', ' . (int) $rang;
1045
            $sql .= ', ' . ($fk_unit ? (int) $fk_unit : 'NULL');
1046
            $sql .= ', ' . (int) $user->id;
1047
            $sql .= ', ' . (int) $this->fk_multicurrency;
1048
            $sql .= ", '" . $this->db->escape($this->multicurrency_code) . "'";
1049
            $sql .= ', ' . price2num($pu_ht_devise, 'CU');
1050
            $sql .= ', ' . price2num($multicurrency_total_ht, 'CT');
1051
            $sql .= ', ' . price2num($multicurrency_total_tva, 'CT');
1052
            $sql .= ', ' . price2num($multicurrency_total_ttc, 'CT');
1053
            $sql .= ')';
1054
1055
            dol_syslog(get_class($this) . '::addline', LOG_DEBUG);
1056
            if ($this->db->query($sql)) {
1057
                $lineId = $this->db->last_insert_id(MAIN_DB_PREFIX . 'facture_fourn_det_rec');
1058
                $this->update_price();
1059
                $this->id = $facid;
1060
                $this->db->commit();
1061
                return $lineId;
1062
            } else {
1063
                $this->db->rollback();
1064
                $this->error = $this->db->lasterror();
1065
1066
                return -1;
1067
            }
1068
        } else {
1069
            $this->error = 'Recurring Invoice is suspended. adding lines not allowed.';
1070
1071
            return -1;
1072
        }
1073
    }
1074
1075
    /**
1076
     * Update a line to supplier invoice template
1077
     *
1078
     * @param int       $rowid              ID
1079
     * @param int       $fk_product         Product/Service ID predefined
1080
     * @param string    $ref                Ref
1081
     * @param string    $label              Label of the line
1082
     * @param string    $desc               Description de la ligne
1083
     * @param double    $pu_ht              Unit price HT (> 0 even for credit note)
1084
     * @param double    $qty                Quantity
1085
     * @param int       $remise_percent     Percentage discount of the line
1086
     * @param double    $txtva              VAT rate forced with format '5.0 (XXX)', or -1
1087
     * @param int       $txlocaltax1        Local tax 1 rate (deprecated)
1088
     * @param int       $txlocaltax2        Local tax 2 rate (deprecated)
1089
     * @param string    $price_base_type    HT or TTC
1090
     * @param int       $type               Type of line (0=product, 1=service)
1091
     * @param int       $date_start         Date start
1092
     * @param int       $date_end           Date end
1093
     * @param int       $info_bits          Bits of type of lines
1094
     * @param int       $special_code       Special code
1095
     * @param int       $rang               Position of line
1096
     * @param string    $fk_unit            Unit
1097
     * @param double    $pu_ht_devise       Unit price in currency
1098
     * @param double    $pu_ttc             Unit price TTC (> 0 even for credit note)
1099
     * @return int                          Return integer <0 if KO, Id of line if OK
1100
     * @throws Exception
1101
     */
1102
    public function updateline($rowid, $fk_product, $ref, $label, $desc, $pu_ht, $qty, $remise_percent, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $price_base_type = 'HT', $type = 0, $date_start = 0, $date_end = 0, $info_bits = 0, $special_code = 0, $rang = -1, $fk_unit = null, $pu_ht_devise = 0, $pu_ttc = 0)
1103
    {
1104
        global $mysoc, $user;
1105
1106
        $facid = $this->id;
1107
1108
        dol_syslog(get_class($this) . '::updateline facid=' . $facid . " rowid=$rowid, desc=$desc, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, fk_product=$fk_product, remise_percent=$remise_percent, info_bits=$info_bits, price_base_type=$price_base_type, pu_ttc=$pu_ttc, type=$type, fk_unit=$fk_unit, pu_ht_devise=$pu_ht_devise", LOG_DEBUG);
1109
        include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php';
1110
1111
        // Check parameters
1112
        if ($type < 0) {
1113
            return -1;
1114
        }
1115
1116
        if ($this->status == self::STATUS_SUSPENDED) {
1117
            // Clean parameters
1118
            $fk_product = empty($fk_product) ? 0 : $fk_product;
1119
            $label = empty($label) ? '' : $label;
1120
            $remise_percent = empty($remise_percent) ? 0 : price2num($remise_percent);
1121
            $qty = price2num($qty);
1122
            $info_bits = empty($info_bits) ? 0 : $info_bits;
1123
            $pu_ht          = price2num($pu_ht);
1124
            $pu_ttc         = price2num($pu_ttc);
1125
            $pu_ht_devise = price2num($pu_ht_devise);
1126
1127
            if (!preg_match('/\((.*)\)/', (string) $txtva)) {
1128
                $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5'
1129
            }
1130
1131
            $txlocaltax1 = empty($txlocaltax1) ? 0 : price2num($txlocaltax1);
1132
            $txlocaltax2 = empty($txlocaltax2) ? 0 : price2num($txlocaltax2);
1133
            $this->multicurrency_total_ht = empty($this->multicurrency_total_ht) ? 0 : $this->multicurrency_total_ht;
1134
            $this->multicurrency_total_tva = empty($this->multicurrency_total_tva) ? 0 : $this->multicurrency_total_tva;
1135
            $this->multicurrency_total_ttc = empty($this->multicurrency_total_ttc) ? 0 : $this->multicurrency_total_ttc;
1136
1137
            $pu = $price_base_type == 'HT' ? $pu_ht : $pu_ttc;
1138
1139
1140
            // Calculate total with, without tax and tax from qty, pu, remise_percent and txtva
1141
            // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
1142
            // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
1143
1144
            $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc);
1145
1146
            // Clean vat code
1147
            $vat_src_code = '';
1148
            $reg = array();
1149
            if (preg_match('/\((.*)\)/', $txtva, $reg)) {
1150
                $vat_src_code = $reg[1];
1151
                $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate.
1152
            }
1153
1154
            $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise);
1155
1156
            $total_ht  = $tabprice[0];
1157
            $total_tva = $tabprice[1];
1158
            $total_ttc = $tabprice[2];
1159
            $total_localtax1 = $tabprice[9];
1160
            $total_localtax2 = $tabprice[10];
1161
            $pu_ht  = $tabprice[3];
1162
            $pu_tva = $tabprice[4];
1163
            $pu_ttc = $tabprice[5];
1164
1165
            // MultiCurrency
1166
            $multicurrency_total_ht  = $tabprice[16];
1167
            $multicurrency_total_tva = $tabprice[17];
1168
            $multicurrency_total_ttc = $tabprice[18];
1169
            $pu_ht_devise = $tabprice[19];
1170
1171
            $product_type = $type;
1172
            if ($fk_product) {
1173
                $product = new Product($this->db);
1174
                $result = $product->fetch($fk_product);
1175
                $product_type = $product->type;
1176
            }
1177
1178
            $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture_fourn_det_rec SET';
1179
            $sql .= ' fk_facture_fourn = ' . ((int) $facid);
1180
            $sql .= ', fk_product = ' . ($fk_product > 0 ? ((int) $fk_product) : 'null');
1181
            $sql .= ", ref = '" . $this->db->escape($ref) . "'";
1182
            $sql .= ", label = '" . $this->db->escape($label) . "'";
1183
            $sql .= ", description = '" . $this->db->escape($desc) . "'";
1184
            $sql .= ', pu_ht = ' . price2num($pu_ht);
1185
            $sql .= ', qty = ' . price2num($qty);
1186
            $sql .= ", remise_percent = '" . price2num($remise_percent) . "'";
1187
            $sql .= ", vat_src_code = '" . $this->db->escape($vat_src_code) . "'";
1188
            $sql .= ', tva_tx = ' . price2num($txtva);
1189
            $sql .= ', localtax1_tx = ' . (float) $txlocaltax1;
1190
            $sql .= ", localtax1_type = '" . $this->db->escape($localtaxes_type[0]) . "'";
1191
            $sql .= ', localtax2_tx = ' . (float) $txlocaltax2;
1192
            $sql .= ", localtax2_type = '" . $this->db->escape($localtaxes_type[2]) . "'";
1193
            $sql .= ", total_ht = '" . price2num($total_ht) . "'";
1194
            $sql .= ", total_tva = '" . price2num($total_tva) . "'";
1195
            $sql .= ", total_localtax1 = '" . price2num($total_localtax1) . "'";
1196
            $sql .= ", total_localtax2 = '" . price2num($total_localtax2) . "'";
1197
            $sql .= ", total_ttc = '" . price2num($total_ttc) . "'";
1198
            $sql .= ', product_type = ' . (int) $product_type;
1199
            $sql .= ', date_start = ' . (empty($date_start) ? 'NULL' : (int) $date_start);
1200
            $sql .= ', date_end = ' . (empty($date_end) ? 'NULL' : (int) $date_end);
1201
            $sql .= ', info_bits = ' . (int) $info_bits;
1202
            $sql .= ', special_code = ' . (int) $special_code;
1203
            $sql .= ', rang = ' . (int) $rang;
1204
            $sql .= ', fk_unit = ' . ($fk_unit ? "'" . $this->db->escape($fk_unit) . "'" : 'null');
1205
            $sql .= ', fk_user_modif = ' . (int) $user;
1206
            $sql .= ', multicurrency_subprice = ' . price2num($pu_ht_devise);
1207
            $sql .= ', multicurrency_total_ht = ' . price2num($multicurrency_total_ht);
1208
            $sql .= ', multicurrency_total_tva = ' . price2num($multicurrency_total_tva);
1209
            $sql .= ', multicurrency_total_ttc = ' . price2num($multicurrency_total_ttc);
1210
            $sql .= ' WHERE rowid = ' . (int) $rowid;
1211
1212
            dol_syslog(get_class($this) . '::updateline', LOG_DEBUG);
1213
            if ($this->db->query($sql)) {
1214
                $this->id = $facid;
1215
                $this->update_price();
1216
                return 1;
1217
            } else {
1218
                $this->error = $this->db->lasterror();
1219
                return -1;
1220
            }
1221
        }
1222
        return 0;
1223
    }
1224
1225
1226
    /**
1227
     * Return next reference of invoice not already used (or last reference)
1228
     *
1229
     * @param    Societe    $soc        Thirdparty object
1230
     * @param    string     $mode       'next' for next value or 'last' for last value
1231
     * @return   string                 free ref or last ref
1232
     */
1233
    public function getNextNumRef($soc, $mode = 'next')
1234
    {
1235
        // Not used for recurring invoices
1236
        return '';
1237
    }
1238
1239
    /**
1240
     * Return the next date of
1241
     *
1242
     * @return  int|false   false if KO, timestamp if OK
1243
     */
1244
    public function getNextDate()
1245
    {
1246
        if (empty($this->date_when)) {
1247
            return false;
1248
        }
1249
        return dol_time_plus_duree($this->date_when, $this->frequency, $this->unit_frequency);
1250
    }
1251
1252
    /**
1253
     * Return if maximum number of generation is reached
1254
     *
1255
     * @return  boolean         False by default, True if maximum number of generation is reached
1256
     */
1257
    public function isMaxNbGenReached()
1258
    {
1259
        $ret = false;
1260
        if ($this->nb_gen_max > 0 && ($this->nb_gen_done >= $this->nb_gen_max)) {
1261
            $ret = true;
1262
        }
1263
        return $ret;
1264
    }
1265
1266
    /**
1267
     * Format string to output with by striking the string if max number of generation was reached
1268
     *
1269
     * @param   string      $ret    Default value to output
1270
     * @return  string              False by default, True if maximum number of generation is reached
1271
     */
1272
    public function strikeIfMaxNbGenReached($ret)
1273
    {
1274
        // Special case to strike the date
1275
        return ($this->isMaxNbGenReached() ? '<strike>' : '') . $ret . ($this->isMaxNbGenReached() ? '</strike>' : '');
1276
    }
1277
1278
    /**
1279
     *  Create all recurrents supplier invoices (for all entities if multicompany is used).
1280
     *  A result may also be provided into this->output.
1281
     *
1282
     *  WARNING: This method changes temporarily the context $conf->entity to be in correct context for each recurring invoice found.
1283
     *
1284
     *  @param  int     $restrictioninvoiceid       0=All qualified template invoices found. > 0 = restrict action on invoice ID
1285
     *  @param  int     $forcevalidation        1=Force validation of invoice whatever is template auto_validate flag.
1286
     *  @return int                             0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK)
1287
     */
1288
    public function createRecurringInvoices($restrictioninvoiceid = 0, $forcevalidation = 0)
1289
    {
1290
        global $conf, $langs, $db, $user, $hookmanager;
1291
1292
        $error = 0;
1293
        $nb_create = 0;
1294
1295
        // Load translation files required by the page
1296
        $langs->loadLangs(array('main', 'bills'));
1297
1298
        $now = dol_now();
1299
        $tmparray = dol_getdate($now);
1300
        $today = dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['year']); // Today is last second of current day
1301
1302
        dol_syslog('createRecurringInvoices restrictioninvoiceid=' . $restrictioninvoiceid . ' forcevalidation=' . $forcevalidation);
1303
1304
        $sql = 'SELECT rowid FROM ' . MAIN_DB_PREFIX . 'facture_fourn_rec';
1305
        $sql .= ' WHERE frequency > 0'; // A recurring supplier invoice is an invoice with a frequency
1306
        $sql .= " AND (date_when IS NULL OR date_when <= '" . $this->db->idate($today) . "')";
1307
        $sql .= ' AND (nb_gen_done < nb_gen_max OR nb_gen_max = 0)';
1308
        $sql .= ' AND suspended = 0';
1309
        $sql .= ' AND entity = ' . (int) $conf->entity; // MUST STAY = $conf->entity here
1310
        if ($restrictioninvoiceid > 0) {
1311
            $sql .= ' AND rowid = ' . (int) $restrictioninvoiceid;
1312
        }
1313
        $sql .= $this->db->order('entity', 'ASC');
1314
        //print $sql;exit;
1315
        $parameters = array(
1316
            'restrictioninvoiceid' => $restrictioninvoiceid,
1317
            'forcevalidation' => $forcevalidation,
1318
        );
1319
        $reshook = $hookmanager->executeHooks('beforeCreationOfRecurringInvoices', $parameters, $sql); // note that $sql might be modified by hooks
1320
1321
        $resql = $this->db->query($sql);
1322
        if ($resql) {
1323
            $i = 0;
1324
            $num = $this->db->num_rows($resql);
1325
1326
            if ($num) {
1327
                $this->output .= $langs->trans('FoundXQualifiedRecurringInvoiceTemplate', $num) . "\n";
1328
            } else {
1329
                $this->output .= $langs->trans('NoQualifiedRecurringInvoiceTemplateFound');
1330
            }
1331
1332
            $saventity = $conf->entity;
1333
            $laststep = "None";
1334
1335
            while ($i < $num) {     // Loop on each template invoice. If $num = 0, test is false at first pass.
1336
                $line = $this->db->fetch_object($resql);
1337
1338
                $this->db->begin();
1339
1340
                $invoiceidgenerated = 0;
1341
1342
                $new_fac_fourn = null;
1343
                $facturerec = new FactureFournisseurRec($this->db);
1344
                $laststep = "Fetch {$line->rowid}";
1345
                $facturerec->fetch($line->rowid);
1346
1347
                if ($facturerec->id > 0) {
1348
                    // Set entity context
1349
                    $conf->entity = $facturerec->entity;
1350
1351
                    dol_syslog('createRecurringInvoices Process invoice template id=' . $facturerec->id . ', ref=' . $facturerec->ref . ', entity=' . $facturerec->entity);
1352
1353
                    $new_fac_fourn = new FactureFournisseur($this->db);
1354
                    $new_fac_fourn->fac_rec = $facturerec->id; // We will create $facture from this recurring invoice
1355
                    $new_fac_fourn->fk_fac_rec_source = $facturerec->id; // We will create $facture from this recurring invoice
1356
1357
                    $new_fac_fourn->type = self::TYPE_STANDARD;
1358
                    $new_fac_fourn->subtype = $facturerec->subtype;
1359
                    $new_fac_fourn->statut = self::STATUS_DRAFT;    // deprecated
1360
                    $new_fac_fourn->status = self::STATUS_DRAFT;
1361
                    $new_fac_fourn->date = empty($facturerec->date_when) ? $now : $facturerec->date_when; // We could also use dol_now here but we prefer date_when so invoice has real date when we would like even if we generate later.
1362
                    $new_fac_fourn->socid = $facturerec->socid;
1363
                    $new_fac_fourn->lines = $facturerec->lines;
1364
                    $new_fac_fourn->ref_supplier = $facturerec->ref_supplier;
1365
                    $new_fac_fourn->model_pdf = $facturerec->model_pdf;
1366
                    $new_fac_fourn->fk_project = $facturerec->fk_project;
1367
                    $new_fac_fourn->label = $facturerec->label;
1368
                    $new_fac_fourn->libelle = $facturerec->label;   // deprecated
0 ignored issues
show
Deprecated Code introduced by
The property FactureFournisseur::$libelle has been deprecated: Use $label ( Ignorable by Annotation )

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

1368
                    /** @scrutinizer ignore-deprecated */ $new_fac_fourn->libelle = $facturerec->label;   // 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...
1369
1370
                    $invoiceidgenerated = $new_fac_fourn->create($user);
1371
                    $laststep = "Create invoiceidgenerated $invoiceidgenerated";
1372
                    if ($invoiceidgenerated <= 0) {
1373
                        $this->errors = $new_fac_fourn->errors;
1374
                        $this->error = $new_fac_fourn->error;
1375
                        $error++;
1376
                    }
1377
                    if (!$error && ($facturerec->auto_validate || $forcevalidation)) {
1378
                        $result = $new_fac_fourn->validate($user);
1379
                        $laststep = "Validate by user {$user->login}";
1380
                        if ($result <= 0) {
1381
                            $this->errors = $new_fac_fourn->errors;
1382
                            $this->error = $new_fac_fourn->error;
1383
                            $error++;
1384
                        }
1385
                    }
1386
1387
                    if (!$error && $facturerec->generate_pdf) {
1388
                        // We refresh the object in order to have all necessary data (like date_lim_reglement)
1389
                        $laststep = "Refresh " . $new_fac_fourn->id;
1390
                        $new_fac_fourn->fetch($new_fac_fourn->id);
1391
                        $laststep = "GenerateDocument " . $new_fac_fourn->id;
1392
                        $result = $new_fac_fourn->generateDocument($facturerec->model_pdf, $langs);
1393
                        if ($result < 0) {
1394
                            $this->errors = $new_fac_fourn->errors;
1395
                            $this->error = $new_fac_fourn->error;
1396
                            $error++;
1397
                        }
1398
                    }
1399
                } else {
1400
                    $error++;
1401
                    $this->error = 'Failed to load invoice template with id=' . $line->rowid . ', entity=' . $conf->entity . "\n";
1402
                    $this->errors[] = 'Failed to load invoice template with id=' . $line->rowid . ', entity=' . $conf->entity;
1403
                    dol_syslog('createRecurringInvoices Failed to load invoice template with id=' . $line->rowid . ', entity=' . $conf->entity);
1404
                }
1405
1406
                if (!$error && $invoiceidgenerated >= 0) {
1407
                    $facturerec->nb_gen_done++;
1408
                    $facturerec->date_last_gen = dol_now();
1409
                    $facturerec->date_when = $facturerec->getNextDate();
1410
                    $facturerec->update($user);
1411
                    $this->db->commit('createRecurringInvoices Process invoice template id=' . $facturerec->id . ', title=' . $facturerec->title);
1412
                    dol_syslog('createRecurringInvoices Process invoice template ' . $facturerec->title . ' is finished with a success generation');
1413
                    $nb_create++;
1414
                    $this->output .= $langs->trans('InvoiceGeneratedFromTemplate', $new_fac_fourn->ref, $facturerec->title) . "\n";
1415
                } else {
1416
                    $this->db->rollback('createRecurringInvoices Process invoice template error=' . $error . ' invoiceidgenerated=' . $invoiceidgenerated . ' LastStep=' . $laststep . ' id=' . $facturerec->id . ', title=' . $facturerec->title);
1417
                }
1418
1419
                $parameters = array(
1420
                    'cpt'        => $i,
1421
                    'total'      => $num,
1422
                    'errorCount' => $error,
1423
                    'invoiceidgenerated' => $invoiceidgenerated,
1424
                    'facturerec' => $facturerec, // it's an object which PHP passes by "reference", so modifiable by hooks.
1425
                    'this'       => $this, // it's an object which PHP passes by "reference", so modifiable by hooks.
1426
                );
1427
                $reshook = $hookmanager->executeHooks('afterCreationOfRecurringInvoice', $parameters, $new_fac_fourn); // note: $facture can be modified by hooks (warning: $facture can be null)
1428
1429
                $i++;
1430
            }
1431
1432
            $conf->entity = $saventity; // Restore entity context
1433
        } else {
1434
            dol_print_error($this->db);
1435
        }
1436
1437
        $this->output = trim($this->output);
1438
1439
        return $error ? $error : 0;
1440
    }
1441
1442
    /**
1443
     *  Return clicable name (with picto eventually)
1444
     *
1445
     * @param   int     $withpicto                  Add picto into link
1446
     * @param  string   $option                     Where point the link
1447
     * @param  int      $max                        Maxlength of ref
1448
     * @param  int      $short                      1=Return just URL
1449
     * @param  string   $moretitle                  Add more text to title tooltip
1450
     * @param   int     $notooltip                  1=Disable tooltip
1451
     * @param  int      $save_lastsearch_value      -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
1452
     * @return string                               String with URL
1453
     */
1454
    public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $moretitle = '', $notooltip = 0, $save_lastsearch_value = -1)
1455
    {
1456
        global $langs, $hookmanager;
1457
1458
        $result = '';
1459
1460
        $label = '<u>' . $langs->trans('RepeatableInvoice') . '</u>';
1461
        if (!empty($this->ref)) {
1462
            $label .= '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
1463
        }
1464
        if ($this->frequency > 0) {
1465
            $label .= '<br><b>' . $langs->trans('Frequency') . ':</b> ' . $langs->trans('FrequencyPer_' . $this->unit_frequency, $this->frequency);
1466
        }
1467
        if (!empty($this->date_last_gen)) {
1468
            $label .= '<br><b>' . $langs->trans('DateLastGeneration') . ':</b> ' . dol_print_date($this->date_last_gen, 'dayhour');
1469
        }
1470
        if ($this->frequency > 0) {
1471
            if (!empty($this->date_when)) {
1472
                $label .= '<br><b>' . $langs->trans('NextDateToExecution') . ':</b> ';
1473
                $label .= (empty($this->suspended) ? '' : '<strike>') . dol_print_date($this->date_when, 'day') . (empty($this->suspended) ? '' : '</strike>'); // No hour for this property
1474
                if (!empty($this->suspended)) {
1475
                    $label .= ' (' . $langs->trans('Disabled') . ')';
1476
                }
1477
            }
1478
        }
1479
1480
        $url = constant('BASE_URL') . '/fourn/facture/card-rec.php?facid=' . $this->id;
1481
1482
        if ($short) {
1483
            return $url;
1484
        }
1485
1486
        if ($option != 'nolink') {
1487
            // Add param to save lastsearch_values or not
1488
            $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1489
            if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER['PHP_SELF'])) {
1490
                $add_save_lastsearch_values = 1;
1491
            }
1492
            if ($add_save_lastsearch_values) {
1493
                $url .= '&save_lastsearch_values=1';
1494
            }
1495
        }
1496
1497
        $linkstart = '<a href="' . $url . '" title="' . dol_escape_htmltag($label, 1) . '" class="classfortooltip">';
1498
        $linkend = '</a>';
1499
1500
        $result .= $linkstart;
1501
        if ($withpicto) {
1502
            $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="' . (($withpicto != 2) ? 'paddingright ' : '') . 'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
1503
        }
1504
        if ($withpicto != 2) {
1505
            $result .= $this->ref;
1506
        }
1507
        $result .= $linkend;
1508
        global $action;
1509
        $hookmanager->initHooks(array($this->element . 'dao'));
1510
        $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1511
        $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1512
        if ($reshook > 0) {
1513
            $result = $hookmanager->resPrint;
1514
        } else {
1515
            $result .= $hookmanager->resPrint;
1516
        }
1517
        return $result;
1518
    }
1519
1520
    /**
1521
     *  Return label of object status
1522
     *
1523
     *  @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
1524
     *  @param      integer $alreadypaid    Not used on recurring invoices
1525
     *  @return     string                  Label of status
1526
     */
1527
    public function getLibStatut($mode = 0, $alreadypaid = -1)
1528
    {
1529
        return $this->LibStatut($this->frequency ? 1 : 0, $this->suspended, $mode, $alreadypaid, empty($this->type) ? 0 : $this->type);
1530
    }
1531
1532
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1533
    /**
1534
     *  Return label of a status
1535
     *
1536
     *  @param      int     $recur          Is it a recurring invoice ?
1537
     *  @param      int     $status         Id status (suspended or not)
1538
     *  @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
1539
     *  @param      integer $alreadypaid    Not used for recurring invoices
1540
     *  @param      int     $type           Type invoice
1541
     *  @return     string                  Label of status
1542
     */
1543
    public function LibStatut($recur, $status, $mode = 0, $alreadypaid = -1, $type = 0)
1544
    {
1545
		// phpcs:enable
1546
        global $langs;
1547
        $langs->load('bills');
1548
1549
        $labelStatus = $langs->transnoentitiesnoconv('Active');
1550
        $statusType = 'status0';
1551
1552
        //print "$recur,$status,$mode,$alreadypaid,$type";
1553
        if ($mode == 0) {
1554
            if ($recur) {
1555
                if ($status == self::STATUS_SUSPENDED) {
1556
                    $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1557
                } else {
1558
                    $labelStatus = $langs->transnoentitiesnoconv('Active');
1559
                }
1560
            } else {
1561
                if ($status == self::STATUS_SUSPENDED) {
1562
                    $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1563
                } else {
1564
                    $labelStatus = $langs->transnoentitiesnoconv('Draft');
1565
                }
1566
            }
1567
        } elseif ($mode == 1) {
1568
            $prefix = 'Short';
1569
            if ($recur) {
1570
                if ($status == self::STATUS_SUSPENDED) {
1571
                    $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1572
                } else {
1573
                    $labelStatus = $langs->transnoentitiesnoconv('Active');
1574
                }
1575
            } else {
1576
                if ($status == self::STATUS_SUSPENDED) {
1577
                    $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1578
                } else {
1579
                    $labelStatus = $langs->transnoentitiesnoconv('Draft');
1580
                }
1581
            }
1582
        } elseif ($mode == 2) {
1583
            if ($recur) {
1584
                if ($status == self::STATUS_SUSPENDED) {
1585
                    $statusType = 'status6';
1586
                    $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1587
                } else {
1588
                    $statusType = 'status4';
1589
                    $labelStatus = $langs->transnoentitiesnoconv('Active');
1590
                }
1591
            } else {
1592
                if ($status == self::STATUS_SUSPENDED) {
1593
                    $statusType = 'status6';
1594
                    $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1595
                } else {
1596
                    $statusType = 'status0';
1597
                    $labelStatus = $langs->transnoentitiesnoconv('Draft');
1598
                }
1599
            }
1600
        } elseif ($mode == 3) {
1601
            if ($recur) {
1602
                $prefix = 'Short';
1603
                if ($status == self::STATUS_SUSPENDED) {
1604
                    $statusType = 'status6';
1605
                    $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1606
                } else {
1607
                    $statusType = 'status4';
1608
                    $labelStatus = $langs->transnoentitiesnoconv('Active');
1609
                }
1610
            } else {
1611
                if ($status == self::STATUS_SUSPENDED) {
1612
                    $statusType = 'status6';
1613
                    $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1614
                } else {
1615
                    $statusType = 'status0';
1616
                    $labelStatus = $langs->transnoentitiesnoconv('Draft');
1617
                }
1618
            }
1619
        } elseif ($mode == 4) {
1620
            $prefix = '';
1621
            if ($recur) {
1622
                if ($status == self::STATUS_SUSPENDED) {
1623
                    $statusType = 'status6';
1624
                    $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1625
                } else {
1626
                    $statusType = 'status4';
1627
                    $labelStatus = $langs->transnoentitiesnoconv('Active');
1628
                }
1629
            } else {
1630
                if ($status == self::STATUS_SUSPENDED) {
1631
                    $statusType = 'status6';
1632
                    $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1633
                } else {
1634
                    $statusType = 'status0';
1635
                    $labelStatus = $langs->transnoentitiesnoconv('Draft');
1636
                }
1637
            }
1638
        } elseif ($mode == 5 || $mode == 6) {
1639
            $prefix = '';
1640
            if ($mode == 5) {
1641
                $prefix = 'Short';
1642
            }
1643
            if ($recur) {
1644
                if ($status == self::STATUS_SUSPENDED) {
1645
                    $statusType = 'status6';
1646
                    $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1647
                } else {
1648
                    $statusType = 'status4';
1649
                    $labelStatus = $langs->transnoentitiesnoconv('Active');
1650
                }
1651
            } else {
1652
                if ($status == self::STATUS_SUSPENDED) {
1653
                    $statusType = 'status6';
1654
                    $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1655
                } else {
1656
                    $statusType = 'status0';
1657
                    $labelStatus = $langs->transnoentitiesnoconv('Draft');
1658
                }
1659
            }
1660
        }
1661
1662
        $labelStatusShort = $labelStatus;
1663
1664
        return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode);
1665
    }
1666
1667
    /**
1668
     *  Initialise an instance with random values.
1669
     *  Used to build previews or test instances.
1670
     *  id must be 0 if object instance is a specimen.
1671
     *
1672
     *  @param  string      $option     ''=Create a specimen invoice with lines, 'nolines'=No lines
1673
     *  @return int
1674
     */
1675
    public function initAsSpecimen($option = '')
1676
    {
1677
        global $user, $langs, $conf;
1678
1679
        $now = dol_now();
1680
        $arraynow = dol_getdate($now);
1681
        $nownotime = dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']);
1682
1683
        // Load array of products prodids
1684
        $num_prods = 0;
1685
        $prodids = array();
1686
1687
        $sql = 'SELECT rowid';
1688
        $sql .= ' FROM ' . MAIN_DB_PREFIX . 'product';
1689
        $sql .= ' WHERE entity IN (' . getEntity('product') . ')';
1690
        $sql .= $this->db->plimit(100);
1691
1692
        $resql = $this->db->query($sql);
1693
        if ($resql) {
1694
            $num_prods = $this->db->num_rows($resql);
1695
            $i = 0;
1696
            while ($i < $num_prods) {
1697
                $i++;
1698
                $row = $this->db->fetch_row($resql);
1699
                $prodids[$i] = $row[0];
1700
            }
1701
        }
1702
1703
        // Initialize parameters
1704
        $this->id = 0;
1705
        $this->ref = 'SPECIMEN';
1706
        $this->title = 'SPECIMEN';
1707
        $this->specimen = 1;
1708
        $this->socid = 1;
1709
        $this->date = $nownotime;
0 ignored issues
show
Documentation Bug introduced by
It seems like $nownotime can also be of type string. However, the property $date 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...
1710
        $this->date_lim_reglement = $nownotime + 3600 * 24 * 30;
1711
        $this->cond_reglement_id   = 1;
1712
        $this->cond_reglement_code = 'RECEP';
1713
        $this->date_lim_reglement = $this->calculate_date_lim_reglement();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->calculate_date_lim_reglement() can also be of type string. However, the property $date_lim_reglement 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...
1714
        $this->mode_reglement_id   = 0; // Not forced to show payment mode CHQ + VIR
1715
        $this->mode_reglement_code = ''; // Not forced to show payment mode CHQ + VIR
1716
        $this->note_public = 'This is a comment (public)';
1717
        $this->note_private = 'This is a comment (private)';
1718
        $this->note = 'This is a comment (private)';
0 ignored issues
show
Deprecated Code introduced by
The property CommonObject::$note has been deprecated: Use $note_private instead. ( Ignorable by Annotation )

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

1718
        /** @scrutinizer ignore-deprecated */ $this->note = 'This is a comment (private)';

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...
1719
        $this->fk_incoterms = 0;
1720
        $this->location_incoterms = '';
1721
1722
        if (empty($option) || $option != 'nolines') {
1723
            // Lines
1724
            $nbp = 5;
1725
            $xnbp = 0;
1726
            while ($xnbp < $nbp) {
1727
                $line = new FactureLigne($this->db);
1728
                $line->desc = $langs->trans('Description') . ' ' . $xnbp;
1729
                $line->qty = 1;
1730
                $line->subprice = 100;
1731
                $line->tva_tx = 19.6;
1732
                $line->localtax1_tx = 0;
1733
                $line->localtax2_tx = 0;
1734
                $line->remise_percent = 0;
1735
                if ($xnbp == 1) {        // Qty is negative (product line)
1736
                    $prodid = mt_rand(1, $num_prods);
1737
                    $line->fk_product = $prodids[$prodid];
1738
                    $line->qty = -1;
1739
                    $line->total_ht = -100;
1740
                    $line->total_ttc = -119.6;
1741
                    $line->total_tva = -19.6;
1742
                } elseif ($xnbp == 2) {    // UP is negative (free line)
1743
                    $line->subprice = -100;
1744
                    $line->total_ht = -100;
1745
                    $line->total_ttc = -119.6;
1746
                    $line->total_tva = -19.6;
1747
                    $line->remise_percent = 0;
1748
                } elseif ($xnbp == 3) {    // Discount is 50% (product line)
1749
                    $prodid = mt_rand(1, $num_prods);
1750
                    $line->fk_product = $prodids[$prodid];
1751
                    $line->total_ht = 50;
1752
                    $line->total_ttc = 59.8;
1753
                    $line->total_tva = 9.8;
1754
                    $line->remise_percent = 50;
1755
                } else { // (product line)
1756
                    $prodid = mt_rand(1, $num_prods);
1757
                    $line->fk_product = $prodids[$prodid];
1758
                    $line->total_ht = 100;
1759
                    $line->total_ttc = 119.6;
1760
                    $line->total_tva = 19.6;
1761
                    $line->remise_percent = 0;
1762
                }
1763
1764
                $this->lines[$xnbp] = $line;
1765
                $xnbp++;
1766
1767
                $this->total_ht       += $line->total_ht;
1768
                $this->total_tva      += $line->total_tva;
1769
                $this->total_ttc      += $line->total_ttc;
1770
            }
1771
            $this->revenuestamp = 0;
1772
1773
            // Add a line "offered"
1774
            $line = new FactureLigne($this->db);
1775
            $line->desc = $langs->trans('Description') . ' (offered line)';
1776
            $line->qty = 1;
1777
            $line->subprice = 100;
1778
            $line->tva_tx = 19.6;
1779
            $line->localtax1_tx = 0;
1780
            $line->localtax2_tx = 0;
1781
            $line->remise_percent = 100;
1782
            $line->total_ht = 0;
1783
            $line->total_ttc = 0; // 90 * 1.196
1784
            $line->total_tva = 0;
1785
            $prodid = mt_rand(1, $num_prods);
1786
            $line->fk_product = $prodids[$prodid];
1787
1788
            $this->lines[$xnbp] = $line;
1789
            $xnbp++;
1790
        }
1791
1792
        $this->usenewprice = 0;
1793
1794
        return 1;
1795
    }
1796
1797
    /**
1798
     * Function used to replace a thirdparty id with another one.
1799
     *
1800
     * @param   DoliDB  $dbs        Database handler, because function is static we name it $dbs not $db to avoid breaking coding test
1801
     * @param   int     $origin_id  Old thirdparty id
1802
     * @param   int     $dest_id    New thirdparty id
1803
     * @return  bool
1804
     */
1805
    public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
1806
    {
1807
        $tables = array(
1808
            'facture_fourn_rec'
1809
        );
1810
1811
        return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
1812
    }
1813
1814
    /**
1815
     *  Update frequency and unit
1816
     *
1817
     *  @param      int     $frequency      value of frequency
1818
     *  @param      string  $unit           unit of frequency  (d, m, y)
1819
     *  @return     int                     Return integer <0 if KO, >0 if OK
1820
     */
1821
    public function setFrequencyAndUnit($frequency, $unit)
1822
    {
1823
        if (!$this->table_element) {
1824
            dol_syslog(get_class($this) . '::setFrequencyAndUnit was called on object with property table_element not defined', LOG_ERR);
1825
            return -1;
1826
        }
1827
1828
        if (!empty($frequency) && empty($unit)) {
1829
            dol_syslog(get_class($this) . '::setFrequencyAndUnit was called on object with params frequency defined but unit not defined', LOG_ERR);
1830
            return -2;
1831
        }
1832
1833
        $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
1834
        $sql .= " SET frequency = " . ($frequency ? ((int) $frequency) : "NULL");
1835
        if (!empty($unit)) {
1836
            $sql .= ", unit_frequency = '" . $this->db->escape($unit) . "'";
1837
        }
1838
        $sql .= " WHERE rowid = " . ((int) $this->id);
1839
1840
        dol_syslog(get_class($this) . '::setFrequencyAndUnit', LOG_DEBUG);
1841
1842
        if ($this->db->query($sql)) {
1843
            $this->frequency = $frequency;
1844
            if (!empty($unit)) {
1845
                $this->unit_frequency = $unit;
1846
            }
1847
            return 1;
1848
        } else {
1849
            $this->error = $this->db->lasterror();
1850
            return -1;
1851
        }
1852
    }
1853
1854
    /**
1855
     *  Update the next date of execution
1856
     *
1857
     *  @param      datetime    $date                   date of execution
1858
     *  @param      int         $increment_nb_gen_done  0 do nothing more, >0 increment nb_gen_done
1859
     *  @return     int                                 Return integer <0 if KO, >0 if OK
1860
     */
1861
    public function setNextDate($date, $increment_nb_gen_done = 0)
1862
    {
1863
        if (!$this->table_element) {
1864
            dol_syslog(get_class($this) . '::setNextDate was called on object with property table_element not defined', LOG_ERR);
1865
            return -1;
1866
        }
1867
        $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
1868
        $sql .= " SET date_when = " . ($date ? "'" . $this->db->idate($date) . "'" : "NULL");
1869
        if ($increment_nb_gen_done > 0) {
1870
            $sql .= ", nb_gen_done = nb_gen_done + 1";
1871
        }
1872
        $sql .= " WHERE rowid = " . (int) $this->id;
1873
1874
        dol_syslog(get_class($this) . '::setNextDate', LOG_DEBUG);
1875
1876
        if ($this->db->query($sql)) {
1877
            $this->date_when = $date;
1878
            if ($increment_nb_gen_done > 0) {
1879
                $this->nb_gen_done++;
1880
            }
1881
            return 1;
1882
        } else {
1883
            $this->error = $this->db->lasterror();
1884
            return -1;
1885
        }
1886
    }
1887
1888
    /**
1889
     *  Update the maximum period
1890
     *
1891
     *  @param      int     $nb     number of maximum period
1892
     *  @return     int             Return integer <0 if KO, >0 if OK
1893
     */
1894
    public function setMaxPeriod($nb)
1895
    {
1896
        if (!$this->table_element) {
1897
            dol_syslog(get_class($this) . '::setMaxPeriod was called on object with property table_element not defined', LOG_ERR);
1898
            return -1;
1899
        }
1900
1901
        if (empty($nb)) {
1902
            $nb = 0;
1903
        }
1904
1905
        $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
1906
        $sql .= " SET nb_gen_max = " . (int) $nb;
1907
        $sql .= " WHERE rowid = " . (int) $this->id;
1908
1909
        dol_syslog(get_class($this) . '::setMaxPeriod', LOG_DEBUG);
1910
1911
        if ($this->db->query($sql)) {
1912
            $this->nb_gen_max = $nb;
1913
            return 1;
1914
        } else {
1915
            dol_print_error($this->db);
1916
            return -1;
1917
        }
1918
    }
1919
1920
    /**
1921
     *  Update the auto validate flag of invoice
1922
     *
1923
     *  @param      int     $validate       0 to create in draft, 1 to create and validate invoice
1924
     *  @return     int                     Return integer <0 if KO, >0 if OK
1925
     */
1926
    public function setAutoValidate($validate)
1927
    {
1928
        if (!$this->table_element) {
1929
            dol_syslog(get_class($this) . '::setAutoValidate was called on object with property table_element not defined', LOG_ERR);
1930
            return -1;
1931
        }
1932
1933
        $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
1934
        $sql .= " SET auto_validate = " . ((int) $validate);
1935
        $sql .= " WHERE rowid = " . (int) $this->id;
1936
1937
        dol_syslog(get_class($this) . '::setAutoValidate', LOG_DEBUG);
1938
1939
        if ($this->db->query($sql)) {
1940
            $this->auto_validate = $validate;
1941
            return 1;
1942
        } else {
1943
            dol_print_error($this->db);
1944
            return -1;
1945
        }
1946
    }
1947
1948
    /**
1949
     *  Update the auto generate documents
1950
     *
1951
     *  @param      int     $validate       0 no document, 1 to generate document
1952
     *  @return     int                     Return integer <0 if KO, >0 if OK
1953
     */
1954
    public function setGeneratePdf($validate)
1955
    {
1956
        if (!$this->table_element) {
1957
            dol_syslog(get_class($this) . '::setGeneratePdf was called on object with property table_element not defined', LOG_ERR);
1958
            return -1;
1959
        }
1960
1961
        $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
1962
        $sql .= " SET generate_pdf = " . (int) $validate;
1963
        $sql .= " WHERE rowid = " . (int) $this->id;
1964
1965
        dol_syslog(get_class($this) . '::setGeneratePdf', LOG_DEBUG);
1966
1967
        if ($this->db->query($sql)) {
1968
            $this->generate_pdf = $validate;
1969
            return 1;
1970
        } else {
1971
            dol_print_error($this->db);
1972
            return -1;
1973
        }
1974
    }
1975
1976
    /**
1977
     *  Update the model for documents
1978
     *
1979
     *  @param      string      $model      model of document generator
1980
     *  @return     int                     Return integer <0 if KO, >0 if OK
1981
     */
1982
    public function setModelPdf($model)
1983
    {
1984
        if (!$this->table_element) {
1985
            dol_syslog(get_class($this) . '::setModelPdf was called on object with property table_element not defined', LOG_ERR);
1986
            return -1;
1987
        }
1988
1989
        $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
1990
        $sql .= " SET modelpdf = '" . $this->db->escape($model) . "'";
1991
        $sql .= " WHERE rowid = " . (int) $this->id;
1992
1993
        dol_syslog(get_class($this) . '::setModelPdf', LOG_DEBUG);
1994
1995
        if ($this->db->query($sql)) {
1996
            $this->model_pdf = $model;
1997
            return 1;
1998
        } else {
1999
            dol_print_error($this->db);
2000
            return -1;
2001
        }
2002
    }
2003
}
2004
2005
2006
2007
/**
2008
 *  Class to manage supplier invoice lines of templates.
2009
 *  Saved into database table llx_facture_fourn_det_rec
2010
 */
2011
class FactureFournisseurLigneRec extends CommonInvoiceLine
2012
{
2013
    /**
2014
     * @var string ID to identify managed object
2015
     */
2016
    public $element = 'invoice_supplier_det_rec';
2017
2018
    /**
2019
     * @var string Name of table without prefix where object is stored
2020
     */
2021
    public $table_element = 'facture_fourn_det_rec';
2022
2023
    public $fk_facture_fourn;
2024
    public $fk_parent;
2025
    public $fk_product;
2026
    public $ref_supplier;
2027
    public $label;
2028
    /**
2029
     * @deprecated  Use desc
2030
     */
2031
    public $description;
2032
    public $pu_ht;
2033
    public $pu_ttc;
2034
2035
    /**
2036
     * @var float Quantity
2037
     */
2038
    public $qty;
2039
    public $remise_percent;
2040
    public $fk_remise_except;
2041
    public $vat_src_code;
2042
    public $tva_tx;
2043
    public $localtax1_tx;
2044
    public $localtax1_type;
2045
    public $localtax2_tx;
2046
    public $localtax2_type;
2047
2048
    public $product_type;
2049
    public $date_start;
2050
    public $date_end;
2051
    public $info_bits;
2052
2053
    /**
2054
     * @var int special code
2055
     */
2056
    public $special_code;
2057
    public $rang;
2058
2059
    public $fk_user_author;
2060
    public $fk_user_modif;
2061
2062
2063
    /**
2064
     *    Delete supplier order template line in database
2065
     *
2066
     * @param User $user Object user
2067
     * @param int $notrigger Disable triggers
2068
     * @return        int                    Return integer <0 if KO, >0 if OK
2069
     */
2070
    public function delete(User $user, $notrigger = 0)
2071
    {
2072
        $error = 0;
2073
        $this->db->begin();
2074
2075
        if (! $error) {
2076
            if (! $notrigger) {
2077
                // Call triggers
2078
                $result = $this->call_trigger('LINESUPPLIERBILLREC_DELETE', $user);
2079
                if ($result < 0) {
2080
                    $error++;
2081
                } // Do also here what you must do to rollback action if trigger fail
2082
                // End call triggers
2083
            }
2084
        }
2085
2086
        if (! $error) {
2087
            $result = $this->deleteExtraFields();
2088
            if ($result < 0) {
2089
                $error++;
2090
            }
2091
        }
2092
2093
        if (! $error) {
2094
            $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element . ' WHERE rowid=' . (int) $this->id;
2095
2096
            $res = $this->db->query($sql);
2097
            if ($res === false) {
2098
                $error++;
2099
                $this->errors[] = $this->db->lasterror();
2100
            }
2101
        }
2102
2103
        // Commit or rollback
2104
        if ($error) {
2105
            $this->db->rollback();
2106
            return -1;
2107
        } else {
2108
            $this->db->commit();
2109
            return 1;
2110
        }
2111
    }
2112
2113
2114
    /**
2115
     *  Get line of template invoice
2116
     *
2117
     *  @param      int     $rowid      Id of invoice
2118
     *  @return     int                 1 if OK, < 0 if KO
2119
     */
2120
    public function fetch($rowid)
2121
    {
2122
        $sql = 'SELECT l.rowid,';
2123
        $sql .= ' l.fk_facture_fourn, l.fk_parent_line, l.fk_product,';
2124
        $sql .= ' l.ref as ref_supplier, l.label, l.description as line_desc, l.pu_ht, l.pu_ttc, l.qty, l.remise_percent, l.fk_remise_except,';
2125
        $sql .= ' l.vat_src_code, l.tva_tx, l.localtax1_tx, l.localtax1_type, l.localtax2_tx, l.localtax2_type,';
2126
        $sql .= ' l.total_ht, l.total_tva, l.total_localtax1, l.total_localtax2, l.total_ttc,';
2127
        $sql .= ' l.product_type, l.date_start, l.date_end,';
2128
        $sql .= ' l.info_bits, l.special_code, l.rang, l.fk_unit, l.import_key,';
2129
        $sql .= ' l.fk_user_author, l.fk_user_modif, l.fk_multicurrency,';
2130
        $sql .= ' l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
2131
        $sql .= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
2132
        $sql .= ' FROM ' . MAIN_DB_PREFIX . 'facture_fourn_det_rec as l';
2133
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'product as p ON l.fk_product = p.rowid';
2134
        $sql .= ' WHERE l.rowid = ' . (int) $rowid;
2135
        $sql .= ' ORDER BY l.rang';
2136
2137
        dol_syslog('FactureRec::fetch', LOG_DEBUG);
2138
        $result = $this->db->query($sql);
2139
        if ($result) {
2140
            $objp = $this->db->fetch_object($result);
2141
2142
            $this->id                       = $objp->rowid;
2143
            $this->fk_facture_fourn         = $objp->fk_facture_fourn;
2144
            $this->fk_parent                = $objp->fk_parent_line;
2145
            $this->fk_product               = $objp->fk_product;
2146
            $this->ref_supplier             = $objp->ref_supplier;
2147
            $this->label                    = $objp->label;
2148
            $this->description              = $objp->line_desc;
0 ignored issues
show
Deprecated Code introduced by
The property FactureFournisseurLigneRec::$description has been deprecated: Use desc ( Ignorable by Annotation )

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

2148
            /** @scrutinizer ignore-deprecated */ $this->description              = $objp->line_desc;

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...
2149
            $this->desc                     = $objp->line_desc;
2150
            $this->pu_ht                    = $objp->pu_ht;
2151
            $this->pu_ttc                   = $objp->pu_ttc;
2152
            $this->qty                      = $objp->qty;
2153
            $this->remise_percent           = $objp->remise_percent;
2154
            $this->fk_remise_except         = $objp->fk_remise_except;
2155
            $this->vat_src_code             = $objp->vat_src_code;
2156
            $this->tva_tx                   = $objp->tva_tx;
2157
            $this->localtax1_tx             = $objp->localtax1_tx;
2158
            $this->localtax1_type           = $objp->localtax1_type;
2159
            $this->localtax2_tx             = $objp->localtax2_tx;
2160
            $this->localtax2_type           = $objp->localtax2_type;
2161
            $this->total_ht                 = $objp->total_ht;
2162
            $this->total_tva                = $objp->total_tva;
2163
            $this->total_localtax1          = $objp->total_localtax1;
2164
            $this->total_localtax2          = $objp->total_localtax2;
2165
            $this->total_ttc                = $objp->total_ttc;
2166
            $this->product_type             = $objp->product_type;
2167
            $this->date_start               = $objp->date_start;
2168
            $this->date_end                 = $objp->date_end;
2169
            $this->info_bits                = $objp->info_bits;
2170
            $this->special_code             = $objp->special_code;
2171
            $this->rang                     = $objp->rang;
2172
            $this->fk_unit                  = $objp->fk_unit;
2173
            $this->import_key               = $objp->import_key;
2174
            $this->fk_user_author           = $objp->fk_user_author;
2175
            $this->fk_user_modif            = $objp->fk_user_modif;
2176
            $this->fk_multicurrency         = $objp->fk_multicurrency;
2177
            $this->multicurrency_code       = $objp->multicurrency_code;
2178
            $this->multicurrency_subprice   = $objp->multicurrency_subprice;
2179
            $this->multicurrency_total_ht   = $objp->multicurrency_total_ht;
2180
            $this->multicurrency_total_tva  = $objp->multicurrency_total_tva;
2181
            $this->multicurrency_total_ttc  = $objp->multicurrency_total_ttc;
2182
2183
            $this->db->free($result);
2184
            return 1;
2185
        } else {
2186
            $this->error = $this->db->lasterror();
2187
            return -3;
2188
        }
2189
    }
2190
2191
2192
    /**
2193
     *  Update a line to supplier invoice template .
2194
     *
2195
     *  @param      User    $user                   User
2196
     *  @param      int     $notrigger              No trigger
2197
     *  @return     int                             Return integer <0 if KO, Id of line if OK
2198
     */
2199
    public function update(User $user, $notrigger = 0)
2200
    {
2201
        global $conf;
2202
2203
        $error = 0;
2204
2205
        include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php';
2206
2207
        $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture_fourn_det_rec SET';
2208
        $sql .= ' fk_facture_fourn = ' . (int) $this->fk_facture_fourn;
2209
        $sql .= ', fk_parent_line = ' . (int) $this->fk_parent;
2210
        $sql .= ', fk_product = ' . (int) $this->fk_product;
2211
        $sql .= ', ref = ' . (!empty($this->ref) ? "'" . $this->db->escape($this->ref) . "'" : 'NULL');
2212
        $sql .= ", label = " . (!empty($this->label) ? "'" . $this->db->escape($this->label) . "'" : 'NULL');
2213
        $sql .= ", description = '" . $this->db->escape($this->desc ? $this->desc : $this->description) . "'";
0 ignored issues
show
Deprecated Code introduced by
The property FactureFournisseurLigneRec::$description has been deprecated: Use desc ( Ignorable by Annotation )

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

2213
        $sql .= ", description = '" . $this->db->escape($this->desc ? $this->desc : /** @scrutinizer ignore-deprecated */ $this->description) . "'";

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...
2214
        $sql .= ', pu_ht = ' . price2num($this->pu_ht);
2215
        $sql .= ', pu_ttc = ' . price2num($this->pu_ttc);
2216
        $sql .= ', qty = ' . price2num($this->qty);
2217
        $sql .= ", remise_percent = '" . price2num($this->remise_percent) . "'";
2218
        $sql .= ', fk_remise_except = ' . (int) $this->fk_remise_except;
2219
        $sql .= ", vat_src_code = '" . $this->db->escape($this->vat_src_code) . "'";
2220
        $sql .= ', tva_tx = ' . price2num($this->tva_tx);
2221
        $sql .= ', localtax1_tx = ' . price2num($this->localtax1_tx);
2222
        $sql .= ", localtax1_type = '" . $this->db->escape($this->localtax1_type) . "'";
2223
        $sql .= ', localtax2_tx = ' . price2num($this->localtax2_tx);
2224
        $sql .= ", localtax2_type = '" . $this->db->escape($this->localtax2_type) . "'";
2225
        if (empty($this->skip_update_total)) {
0 ignored issues
show
Bug Best Practice introduced by
The property skip_update_total does not exist on FactureFournisseurLigneRec. Since you implemented __get, consider adding a @property annotation.
Loading history...
2226
            $sql .= ', total_ht = ' . price2num($this->total_ht);
2227
            $sql .= ', total_tva = ' . price2num($this->total_tva);
2228
            $sql .= ', total_localtax1 = ' . price2num($this->total_localtax1);
2229
            $sql .= ', total_localtax2 = ' . price2num($this->total_localtax2);
2230
            $sql .= ', total_ttc = ' . price2num($this->total_ttc);
2231
        }
2232
        $sql .= ', product_type = ' . (int) $this->product_type;
2233
        $sql .= ', date_start = ' . (int) $this->date_start;
2234
        $sql .= ', date_end = ' . (int) $this->date_end;
2235
        $sql .= ", info_bits = " . ((int) $this->info_bits);
2236
        $sql .= ', special_code =' . (int) $this->special_code;
2237
        $sql .= ', rang = ' . (int) $this->rang;
2238
        $sql .= ', fk_unit = ' . ($this->fk_unit ? "'" . $this->db->escape($this->fk_unit) . "'" : 'null');
2239
        $sql .= ', fk_user_modif = ' . (int) $user->id;
2240
        $sql .= ' WHERE rowid = ' . (int) $this->id;
2241
2242
        $this->db->begin();
2243
2244
        dol_syslog(get_class($this) . '::updateline', LOG_DEBUG);
2245
        $resql = $this->db->query($sql);
2246
        if ($resql) {
2247
            if (!$error) {
2248
                $result = $this->insertExtraFields();
2249
                if ($result < 0) {
2250
                    $error++;
2251
                }
2252
            }
2253
2254
            if (!$error && !$notrigger) {
2255
                // Call trigger
2256
                $result = $this->call_trigger('LINESUPPLIERBILLREC_MODIFY', $user);
2257
                if ($result < 0) {
2258
                    $error++;
2259
                }
2260
                // End call triggers
2261
            }
2262
2263
            if ($error) {
2264
                $this->db->rollback();
2265
                return -2;
2266
            } else {
2267
                $this->db->commit();
2268
                return 1;
2269
            }
2270
        } else {
2271
            $this->error = $this->db->lasterror();
2272
            $this->db->rollback();
2273
            return -2;
2274
        }
2275
    }
2276
}
2277