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

SupplierInvoiceLine::delete()   B

Complexity

Conditions 8
Paths 54

Size

Total Lines 45
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 27
nc 54
nop 1
dl 0
loc 45
rs 8.4444
c 1
b 0
f 0
1
<?php
2
3
/* Copyright (C) 2002-2004  Rodolphe Quiedeville        <[email protected]>
4
 * Copyright (C) 2004-2012	Laurent Destailleur		    <[email protected]>
5
 * Copyright (C) 2004		Christophe Combelles	    <[email protected]>
6
 * Copyright (C) 2005		Marc Barilley			    <[email protected]>
7
 * Copyright (C) 2005-2012	Regis Houssin			    <[email protected]>
8
 * Copyright (C) 2010-2020	Juanjo Menent			    <[email protected]>
9
 * Copyright (C) 2013-2019	Philippe Grand			    <[email protected]>
10
 * Copyright (C) 2013		Florian Henry			    <[email protected]>
11
 * Copyright (C) 2014-2016	Marcos García			    <[email protected]>
12
 * Copyright (C) 2015		Bahfir Abbes			    <[email protected]>
13
 * Copyright (C) 2015-2022	Ferran Marcet			    <[email protected]>
14
 * Copyright (C) 2016-2023	Alexandre Spangaro		    <[email protected]>
15
 * Copyright (C) 2018       Nicolas ZABOURI			    <[email protected]>
16
 * Copyright (C) 2018-2024  Frédéric France             <[email protected]>
17
 * Copyright (C) 2022      	Gauthier VERDOL     	    <[email protected]>
18
 * Copyright (C) 2023		Nick Fragoulis
19
 * Copyright (C) 2024		MDW							<[email protected]>
20
 * Copyright (C) 2024       Rafael San José             <[email protected]>
21
 *
22
 * This program is free software; you can redistribute it and/or modify
23
 * it under the terms of the GNU General Public License as published by
24
 * the Free Software Foundation; either version 3 of the License, or
25
 * (at your option) any later version.
26
 *
27
 * This program is distributed in the hope that it will be useful,
28
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30
 * GNU General Public License for more details.
31
 *
32
 * You should have received a copy of the GNU General Public License
33
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
34
 */
35
36
namespace Dolibarr\Code\Fourn\Classes;
37
38
use Dolibarr\Code\Accountancy\Classes\AccountingAccount;
39
40
/**
41
 *  \file       htdocs/fourn/class/fournisseur.facture.class.php
42
 *  \ingroup    fournisseur,facture
43
 *  \brief      File of class to manage suppliers invoices
44
 */
45
46
use Dolibarr\Code\MultiCurrency\Classes\MultiCurrency;
47
48
use Dolibarr\Core\Base\CommonObjectLine;
49
50
if (isModEnabled('accounting')) {
51
}
52
53
/**
54
 *  Class to manage line invoices
55
 */
56
class SupplierInvoiceLine extends CommonObjectLine
57
{
58
    /**
59
     * @var string ID to identify managed object
60
     */
61
    public $element = 'facture_fourn_det';
62
63
    /**
64
     * @var string Name of table without prefix where object is stored
65
     */
66
    public $table_element = 'facture_fourn_det';
67
68
    /**
69
     * @see CommonObjectLine
70
     */
71
    public $parent_element = 'facture_fourn';
72
73
    /**
74
     * @see CommonObjectLine
75
     */
76
    public $fk_parent_attribute = 'fk_facture_fourn';
77
78
    /**
79
     * @var static
80
     */
81
    public $oldline;
82
83
    /**
84
     * @deprecated
85
     * @see $product_ref
86
     */
87
    public $ref;
88
89
    /**
90
     * Internal ref
91
     * @var string
92
     */
93
    public $product_ref;
94
95
    /**
96
     * Supplier reference of price when we added the line. May have been changed after line was added.
97
     * TODO Rename field ref to ref_supplier into table llx_facture_fourn_det and llx_commande_fournisseurdet and update fields into updateline
98
     * @var string
99
     */
100
    public $ref_supplier;
101
102
    /**
103
     * Product description
104
     * @var string
105
     */
106
    public $product_desc;
107
108
    /**
109
     * Unit price before taxes
110
     * @var float
111
     * @deprecated Use $subprice
112
     * @see $subprice
113
     */
114
    public $pu_ht;
115
116
    /**
117
     * Unit price excluded taxes
118
     * @var float
119
     */
120
    public $subprice;
121
122
    /**
123
     * Unit price included taxes
124
     * @var float
125
     */
126
    public $pu_ttc;
127
128
129
    /**
130
     * Id of the corresponding supplier invoice
131
     * @var int
132
     */
133
    public $fk_facture_fourn;
134
135
    /**
136
     * This field may contains label of line (when invoice create from order)
137
     * @var string
138
     * @deprecated  Use $product_label
139
     */
140
    public $label;
141
142
    /**
143
     * Description of the line
144
     * @var string
145
     * @deprecated      Use $desc
146
     */
147
    public $description;
148
149
    public $date_start;
150
    public $date_end;
151
152
    /**
153
     * @var int
154
     */
155
    public $fk_code_ventilation;
156
157
    /**
158
     * @var int<0,1>
159
     */
160
    public $skip_update_total; // Skip update price total for special lines
161
162
    /**
163
     * @var float   Situation progress percentage
164
     */
165
    public $situation_percent;
166
167
    /**
168
     * @var int     Previous situation line id reference
169
     */
170
    public $fk_prev_id;
171
172
    /**
173
     * VAT code
174
     * @var string
175
     */
176
    public $vat_src_code;
177
178
    /**
179
     * VAT %
180
     * @var float
181
     */
182
    public $tva_tx;
183
184
    /**
185
     * Local tax 1 %
186
     * @var float
187
     */
188
    public $localtax1_tx;
189
190
    /**
191
     * Local tax 2 %
192
     * @var float
193
     */
194
    public $localtax2_tx;
195
196
    /**
197
     * Quantity
198
     * @var float
199
     */
200
    public $qty;
201
202
    /**
203
     * Percent of discount
204
     * @var float
205
     */
206
    public $remise_percent;
207
208
    /**
209
     * Buying price value
210
     * @var float
211
     */
212
    public $pa_ht;
213
214
    /**
215
     * Total amount without taxes
216
     * @var float
217
     */
218
    public $total_ht;
219
220
    /**
221
     * Total amount with taxes
222
     * @var float
223
     */
224
    public $total_ttc;
225
226
    /**
227
     * Total amount of taxes
228
     * @var float
229
     */
230
    public $total_tva;
231
232
    /**
233
     * Total local tax 1 amount
234
     * @var float
235
     */
236
    public $total_localtax1;
237
238
    /**
239
     * Total local tax 2 amount
240
     * @var float
241
     */
242
    public $total_localtax2;
243
244
    /**
245
     * @var int ID
246
     */
247
    public $fk_product;
248
249
    /**
250
     * Type of the product. 0 for product 1 for service
251
     * @var int
252
     */
253
    public $product_type;
254
255
    /**
256
     * Label of the product
257
     * @var string
258
     */
259
    public $product_label;
260
261
    /**
262
     * List of cumulative options:
263
     * Bit 0:   0 si TVA normal - 1 si TVA NPR
264
     * Bit 1:   0 si ligne normal - 1 si bit discount (link to line into llx_remise_except)
265
     * @var int
266
     */
267
    public $info_bits;
268
269
    /**
270
     * Link to line into llx_remise_except
271
     * @var int
272
     */
273
    public $fk_remise_except;
274
275
    /**
276
     * @var int ID
277
     */
278
    public $fk_parent_line;
279
280
    /**
281
     * @var int special code
282
     */
283
    public $special_code;
284
285
    /**
286
     * @var int rank of line
287
     */
288
    public $rang;
289
290
    /**
291
     * Total local tax 1 amount
292
     * @var float
293
     */
294
    public $localtax1_type;
295
296
    /**
297
     * Total local tax 2 amount
298
     * @var float
299
     */
300
    public $localtax2_type;
301
302
303
    /**
304
     *  Constructor
305
     *
306
     *  @param      DoliDB      $db      Database handler
0 ignored issues
show
Bug introduced by
The type Dolibarr\Code\Fourn\Classes\DoliDB was not found. Did you mean DoliDB? If so, make sure to prefix the type with \.
Loading history...
307
     */
308
    public function __construct($db)
309
    {
310
        $this->db = $db;
311
    }
312
313
    /**
314
     * Retrieves a supplier invoice line
315
     *
316
     * @param    int    $rowid    Line id
317
     * @return   int              Return integer <0 KO; 0 NOT FOUND; 1 OK
318
     */
319
    public function fetch($rowid)
320
    {
321
        $sql = 'SELECT f.rowid, f.ref as ref_supplier, f.description as line_desc, f.date_start, f.date_end, f.pu_ht, f.pu_ttc, f.qty, f.remise_percent, f.tva_tx';
322
        $sql .= ', f.localtax1_type, f.localtax2_type, f.localtax1_tx, f.localtax2_tx, f.total_localtax1, f.total_localtax2, f.fk_remise_except';
323
        $sql .= ', f.total_ht, f.tva as total_tva, f.total_ttc, f.fk_facture_fourn, f.fk_product, f.product_type, f.info_bits, f.rang, f.special_code, f.fk_parent_line, f.fk_unit';
324
        $sql .= ', p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.description as product_desc';
325
        $sql .= ', f.multicurrency_subprice, f.multicurrency_total_ht, f.multicurrency_total_tva, multicurrency_total_ttc';
326
        $sql .= ' FROM ' . MAIN_DB_PREFIX . 'facture_fourn_det as f';
327
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'product as p ON f.fk_product = p.rowid';
328
        $sql .= ' WHERE f.rowid = ' . ((int) $rowid);
329
        $sql .= ' ORDER BY f.rang, f.rowid';
330
331
        $query = $this->db->query($sql);
332
333
        if (!$query) {
334
            $this->errors[] = $this->db->error();
335
            return -1;
336
        }
337
338
        if (!$this->db->num_rows($query)) {
339
            return 0;
340
        }
341
342
        $obj = $this->db->fetch_object($query);
343
344
        $this->id = $obj->rowid;
345
        $this->rowid = $obj->rowid;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObjectLine::$rowid has been deprecated: Try to use id property as possible (even if field into database is still rowid) ( Ignorable by Annotation )

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

345
        /** @scrutinizer ignore-deprecated */ $this->rowid = $obj->rowid;

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...
346
        $this->fk_facture_fourn = $obj->fk_facture_fourn;
347
        $this->description      = $obj->line_desc;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Fourn\Clas...voiceLine::$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

347
        /** @scrutinizer ignore-deprecated */ $this->description      = $obj->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...
348
        $this->desc             = $obj->line_desc;
349
        $this->date_start = $obj->date_start;
350
        $this->date_end = $obj->date_end;
351
        $this->product_ref      = $obj->product_ref;
352
        $this->ref_supplier     = $obj->ref_supplier;
353
        $this->product_desc     = $obj->product_desc;
354
355
        $this->subprice = $obj->pu_ht;
356
        $this->pu_ht = $this->subprice;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Fourn\Clas...lierInvoiceLine::$pu_ht has been deprecated: Use $subprice ( Ignorable by Annotation )

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

356
        /** @scrutinizer ignore-deprecated */ $this->pu_ht = $this->subprice;

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...
357
        $this->pu_ttc           = $obj->pu_ttc;
358
        $this->tva_tx           = $obj->tva_tx;
359
        $this->localtax1_tx     = $obj->localtax1_tx;
360
        $this->localtax2_tx     = $obj->localtax2_tx;
361
        $this->localtax1_type   = $obj->localtax1_type;
362
        $this->localtax2_type   = $obj->localtax2_type;
363
364
        $this->qty              = $obj->qty;
365
        $this->remise_percent = $obj->remise_percent;
366
        $this->fk_remise_except = $obj->fk_remise_except;
367
        //$this->tva                = $obj->total_tva; // deprecated
368
        $this->total_ht = $obj->total_ht;
369
        $this->total_tva            = $obj->total_tva;
370
        $this->total_localtax1  = $obj->total_localtax1;
371
        $this->total_localtax2  = $obj->total_localtax2;
372
        $this->total_ttc            = $obj->total_ttc;
373
        $this->fk_product       = $obj->fk_product;
374
        $this->product_type = $obj->product_type;
375
        $this->product_label        = $obj->product_label;
376
        $this->label        = $obj->product_label;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Fourn\Clas...lierInvoiceLine::$label has been deprecated: Use $product_label ( Ignorable by Annotation )

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

376
        /** @scrutinizer ignore-deprecated */ $this->label        = $obj->product_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...
377
        $this->info_bits            = $obj->info_bits;
378
        $this->fk_parent_line    = $obj->fk_parent_line;
379
        $this->special_code = $obj->special_code;
380
        $this->rang = $obj->rang;
381
        $this->fk_unit           = $obj->fk_unit;
382
383
        $this->multicurrency_subprice = $obj->multicurrency_subprice;
384
        $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
385
        $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
386
        $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
387
388
        $this->fetch_optionals();
389
390
        return 1;
391
    }
392
393
    /**
394
     * Deletes a line
395
     *
396
     * @param     int   $notrigger     1=Does not execute triggers, 0=execute triggers
397
     * @return    int                  0 if KO, 1 if OK
398
     */
399
    public function delete($notrigger = 0)
400
    {
401
        global $user;
402
403
        dol_syslog(get_class($this) . "::deleteline rowid=" . ((int) $this->id), LOG_DEBUG);
404
405
        $error = 0;
406
407
        $this->db->begin();
408
409
        if (!$notrigger) {
410
            if ($this->call_trigger('LINEBILL_SUPPLIER_DELETE', $user) < 0) {
411
                $error++;
412
            }
413
        }
414
415
        $this->deleteObjectLinked();
416
417
        // Remove extrafields
418
        if (!$error) {
419
            $result = $this->deleteExtraFields();
420
            if ($result < 0) {
421
                $error++;
422
                dol_syslog(get_class($this) . "::delete error -4 " . $this->error, LOG_ERR);
423
            }
424
        }
425
426
        if (!$error) {
427
            // Supprime ligne
428
            $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'facture_fourn_det ';
429
            $sql .= " WHERE rowid = " . ((int) $this->id);
430
            dol_syslog(get_class($this) . "::delete", LOG_DEBUG);
431
            $resql = $this->db->query($sql);
432
            if (!$resql) {
433
                $error++;
434
                $this->error = $this->db->lasterror();
435
            }
436
        }
437
438
        if (!$error) {
439
            $this->db->commit();
440
            return 1;
441
        } else {
442
            $this->db->rollback();
443
            return -1;
444
        }
445
    }
446
447
    /**
448
     * Update a supplier invoice line
449
     *
450
     * @param int $notrigger Disable triggers
451
     * @return int Return integer <0 if KO, >0 if OK
452
     */
453
    public function update($notrigger = 0)
454
    {
455
        global $conf;
456
457
        $pu = price2num($this->subprice);
458
        $qty = price2num($this->qty);
459
460
        // Check parameters
461
        if (empty($this->qty)) {
462
            $this->qty = 0;
463
        }
464
465
        if ($this->product_type < 0) {
466
            return -1;
467
        }
468
469
        // Clean parameters
470
        if (empty($this->remise_percent)) {
471
            $this->remise_percent = 0;
472
        }
473
        if (empty($this->tva_tx)) {
474
            $this->tva_tx = 0;
475
        }
476
        if (empty($this->localtax1_tx)) {
477
            $this->localtax1_tx = 0;
478
        }
479
        if (empty($this->localtax2_tx)) {
480
            $this->localtax2_tx = 0;
481
        }
482
483
        if (empty($this->pa_ht)) {
484
            $this->pa_ht = 0;
485
        }
486
        if (empty($this->multicurrency_subprice)) {
487
            $this->multicurrency_subprice = 0;
488
        }
489
        if (empty($this->multicurrency_total_ht)) {
490
            $this->multicurrency_total_ht = 0;
491
        }
492
        if (empty($this->multicurrency_total_tva)) {
493
            $this->multicurrency_total_tva = 0;
494
        }
495
        if (empty($this->multicurrency_total_ttc)) {
496
            $this->multicurrency_total_ttc = 0;
497
        }
498
499
        $fk_product = (int) $this->fk_product;
500
        $fk_unit = (int) $this->fk_unit;
501
502
        $this->db->begin();
503
504
        $sql = "UPDATE " . MAIN_DB_PREFIX . "facture_fourn_det SET";
505
        $sql .= " description = '" . $this->db->escape(empty($this->description) ? $this->desc : $this->description) . "'";
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Fourn\Clas...voiceLine::$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

505
        $sql .= " description = '" . $this->db->escape(empty($this->description) ? $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...
506
        $sql .= ", ref = '" . $this->db->escape($this->ref_supplier ? $this->ref_supplier : $this->ref) . "'";
507
        $sql .= ", date_start = " . ($this->date_start != '' ? "'" . $this->db->idate($this->date_start) . "'" : "null");
508
        $sql .= ", date_end = " . ($this->date_end != '' ? "'" . $this->db->idate($this->date_end) . "'" : "null");
509
        $sql .= ", pu_ht = " . price2num($this->subprice);
510
        $sql .= ", pu_ttc = " . price2num($this->pu_ttc);
511
        $sql .= ", qty = " . price2num($this->qty);
512
        $sql .= ", remise_percent = " . price2num($this->remise_percent);
513
        if ($this->fk_remise_except > 0) {
514
            $sql .= ", fk_remise_except=" . ((int) $this->fk_remise_except);
515
        } else {
516
            $sql .= ", fk_remise_except=null";
517
        }
518
        $sql .= ", vat_src_code = '" . $this->db->escape(empty($this->vat_src_code) ? '' : $this->vat_src_code) . "'";
519
        $sql .= ", tva_tx = " . price2num($this->tva_tx);
520
        $sql .= ", localtax1_tx = " . price2num($this->localtax1_tx);
521
        $sql .= ", localtax2_tx = " . price2num($this->localtax2_tx);
522
        $sql .= ", localtax1_type = '" . $this->db->escape($this->localtax1_type) . "'";
523
        $sql .= ", localtax2_type = '" . $this->db->escape($this->localtax2_type) . "'";
524
        $sql .= ", total_ht = " . price2num($this->total_ht);
525
        $sql .= ", tva= " . price2num($this->total_tva);
526
        $sql .= ", total_localtax1= " . price2num($this->total_localtax1);
527
        $sql .= ", total_localtax2= " . price2num($this->total_localtax2);
528
        $sql .= ", total_ttc = " . price2num($this->total_ttc);
529
        $sql .= ", fk_product = " . ($fk_product > 0 ? (int) $fk_product : 'null');
530
        $sql .= ", product_type = " . ((int) $this->product_type);
531
        $sql .= ", info_bits = " . ((int) $this->info_bits);
532
        $sql .= ", fk_unit = " . ($fk_unit > 0 ? (int) $fk_unit : 'null');
533
534
        if (!empty($this->rang)) {
535
            $sql .= ", rang=" . ((int) $this->rang);
536
        }
537
538
        // Multicurrency
539
        $sql .= " , multicurrency_subprice=" . price2num($this->multicurrency_subprice);
540
        $sql .= " , multicurrency_total_ht=" . price2num($this->multicurrency_total_ht);
541
        $sql .= " , multicurrency_total_tva=" . price2num($this->multicurrency_total_tva);
542
        $sql .= " , multicurrency_total_ttc=" . price2num($this->multicurrency_total_ttc);
543
544
        $sql .= " WHERE rowid = " . ((int) $this->id);
545
546
        dol_syslog(get_class($this) . "::update", LOG_DEBUG);
547
        $resql = $this->db->query($sql);
548
549
        if (!$resql) {
550
            $this->db->rollback();
551
            $this->error = $this->db->lasterror();
552
            return -1;
553
        }
554
555
        $this->rowid = $this->id;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObjectLine::$rowid has been deprecated: Try to use id property as possible (even if field into database is still rowid) ( Ignorable by Annotation )

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

555
        /** @scrutinizer ignore-deprecated */ $this->rowid = $this->id;

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

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

Loading history...
556
        $error = 0;
557
558
        if (!$error) {
559
            $result = $this->insertExtraFields();
560
            if ($result < 0) {
561
                $error++;
562
            }
563
        }
564
565
        if (!$error && !$notrigger) {
566
            global $langs, $user;
567
568
            // Call trigger
569
            if ($this->call_trigger('LINEBILL_SUPPLIER_MODIFY', $user) < 0) {
570
                $this->db->rollback();
571
                return -1;
572
            }
573
            // End call triggers
574
        }
575
576
        if ($error) {
577
            $this->db->rollback();
578
            return -1;
579
        }
580
581
        $this->db->commit();
582
        return 1;
583
    }
584
585
    /**
586
     *  Insert line into database
587
     *
588
     *  @param      int     $notrigger                          1 no triggers
589
     *  @param      int     $noerrorifdiscountalreadylinked     1=Do not make error if lines is linked to a discount and discount already linked to another
590
     *  @return     int                                         Return integer <0 if KO, >0 if OK
591
     */
592
    public function insert($notrigger = 0, $noerrorifdiscountalreadylinked = 0)
593
    {
594
        global $user, $langs;
595
596
        $error = 0;
597
598
        dol_syslog(get_class($this) . "::insert rang=" . $this->rang, LOG_DEBUG);
599
600
        // Clean parameters
601
        $this->desc = trim($this->desc);
602
        if (empty($this->tva_tx)) {
603
            $this->tva_tx = 0;
604
        }
605
        if (empty($this->localtax1_tx)) {
606
            $this->localtax1_tx = 0;
607
        }
608
        if (empty($this->localtax2_tx)) {
609
            $this->localtax2_tx = 0;
610
        }
611
        if (empty($this->localtax1_type)) {
612
            $this->localtax1_type = 0.0;
613
        }
614
        if (empty($this->localtax2_type)) {
615
            $this->localtax2_type = 0.0;
616
        }
617
        if (empty($this->total_tva)) {
618
            $this->total_tva = 0;
619
        }
620
        if (empty($this->total_localtax1)) {
621
            $this->total_localtax1 = 0;
622
        }
623
        if (empty($this->total_localtax2)) {
624
            $this->total_localtax2 = 0;
625
        }
626
        if (empty($this->rang)) {
627
            $this->rang = 0;
628
        }
629
        if (empty($this->remise_percent)) {
630
            $this->remise_percent = 0;
631
        }
632
        if (empty($this->info_bits)) {
633
            $this->info_bits = 0;
634
        }
635
        if (empty($this->subprice)) {
636
            $this->subprice = 0;
637
        }
638
        if (empty($this->special_code)) {
639
            $this->special_code = 0;
640
        }
641
        if (empty($this->fk_parent_line)) {
642
            $this->fk_parent_line = 0;
643
        }
644
        if (!isset($this->situation_percent) || $this->situation_percent > 100 || (string) $this->situation_percent == '') {
645
            $this->situation_percent = 100;
646
        }
647
648
        if (empty($this->pa_ht)) {
649
            $this->pa_ht = 0;
650
        }
651
        if (empty($this->multicurrency_subprice)) {
652
            $this->multicurrency_subprice = 0;
653
        }
654
        if (empty($this->multicurrency_total_ht)) {
655
            $this->multicurrency_total_ht = 0;
656
        }
657
        if (empty($this->multicurrency_total_tva)) {
658
            $this->multicurrency_total_tva = 0;
659
        }
660
        if (empty($this->multicurrency_total_ttc)) {
661
            $this->multicurrency_total_ttc = 0;
662
        }
663
664
665
        // Check parameters
666
        if ($this->product_type < 0) {
667
            $this->error = 'ErrorProductTypeMustBe0orMore';
668
            return -1;
669
        }
670
        if (!empty($this->fk_product) && $this->fk_product > 0) {
671
            // Check product exists
672
            $result = Product::isExistingObject('product', $this->fk_product);
673
            if ($result <= 0) {
674
                $this->error = 'ErrorProductIdDoesNotExists';
675
                return -1;
676
            }
677
        }
678
679
        $this->db->begin();
680
681
        // Insertion dans base de la ligne
682
        $sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element;
683
        $sql .= ' (fk_facture_fourn, fk_parent_line, label, description, ref, qty,';
684
        $sql .= ' vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
685
        $sql .= ' fk_product, product_type, remise_percent, fk_remise_except, pu_ht, pu_ttc,';
686
        $sql .= ' date_start, date_end, fk_code_ventilation, rang, special_code,';
687
        $sql .= ' info_bits, total_ht, tva, total_ttc, total_localtax1, total_localtax2, fk_unit';
688
        $sql .= ', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc';
689
        $sql .= ')';
690
        $sql .= " VALUES (" . $this->fk_facture_fourn . ",";
691
        $sql .= " " . ($this->fk_parent_line > 0 ? "'" . $this->db->escape($this->fk_parent_line) . "'" : "null") . ",";
692
        $product_label
693
            = !empty($this->product_label)
694
              ? $this->product_label :
695
                (!empty($this->label) ? $this->label : null);
696
        $sql .= " " . (!empty($product_label) ? "'" . $this->db->escape($product_label) . "'" : "null") . ",";
697
        $sql .= " '" . $this->db->escape($this->desc ? $this->desc : $this->description) . "',";
698
        $sql .= " '" . $this->db->escape($this->ref_supplier) . "',";
699
        $sql .= " " . price2num($this->qty) . ",";
700
701
        $sql .= " " . (empty($this->vat_src_code) ? "''" : "'" . $this->db->escape($this->vat_src_code) . "'") . ",";
702
        $sql .= " " . price2num($this->tva_tx) . ",";
703
        $sql .= " " . price2num($this->localtax1_tx) . ",";
704
        $sql .= " " . price2num($this->localtax2_tx) . ",";
705
        $sql .= " '" . $this->db->escape($this->localtax1_type) . "',";
706
        $sql .= " '" . $this->db->escape($this->localtax2_type) . "',";
707
        $sql .= ' ' . ((!empty($this->fk_product) && $this->fk_product > 0) ? $this->fk_product : "null") . ',';
708
        $sql .= " " . ((int) $this->product_type) . ",";
709
        $sql .= " " . price2num($this->remise_percent) . ",";
710
        $sql .= ' ' . (!empty($this->fk_remise_except) ? ((int) $this->fk_remise_except) : "null") . ',';
711
        $sql .= " " . price2num($this->subprice) . ",";
712
        $sql .= " " . (!empty($this->qty) ? price2num($this->total_ttc / $this->qty) : price2num($this->total_ttc)) . ",";
713
        $sql .= " " . (!empty($this->date_start) ? "'" . $this->db->idate($this->date_start) . "'" : "null") . ",";
714
        $sql .= " " . (!empty($this->date_end) ? "'" . $this->db->idate($this->date_end) . "'" : "null") . ",";
715
        $sql .= ' ' . (!empty($this->fk_code_ventilation) ? $this->fk_code_ventilation : 0) . ',';
716
        $sql .= ' ' . ((int) $this->rang) . ',';
717
        $sql .= ' ' . ((int) $this->special_code) . ',';
718
        $sql .= " " . ((int) $this->info_bits) . ",";
719
        $sql .= " " . price2num($this->total_ht) . ",";
720
        $sql .= " " . price2num($this->total_tva) . ",";
721
        $sql .= " " . price2num($this->total_ttc) . ",";
722
        $sql .= " " . price2num($this->total_localtax1) . ",";
723
        $sql .= " " . price2num($this->total_localtax2);
724
        $sql .= ", " . (!$this->fk_unit ? 'NULL' : $this->fk_unit);
725
        $sql .= ", " . (int) $this->fk_multicurrency;
726
        $sql .= ", '" . $this->db->escape($this->multicurrency_code) . "'";
727
        $sql .= ", " . price2num($this->multicurrency_subprice);
728
        $sql .= ", " . price2num($this->multicurrency_total_ht);
729
        $sql .= ", " . price2num($this->multicurrency_total_tva);
730
        $sql .= ", " . price2num($this->multicurrency_total_ttc);
731
        $sql .= ')';
732
733
        $resql = $this->db->query($sql);
734
        if ($resql) {
735
            $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element);
736
            $this->rowid = $this->id; // backward compatibility
737
738
            if (!$error) {
739
                $result = $this->insertExtraFields();
740
                if ($result < 0) {
741
                    $error++;
742
                }
743
            }
744
745
            // Si fk_remise_except defini, on lie la remise a la facture
746
            // ce qui la flague comme "consommee".
747
            if ($this->fk_remise_except) {
748
                $discount = new DiscountAbsolute($this->db);
749
                $result = $discount->fetch($this->fk_remise_except);
750
                if ($result >= 0) {
751
                    // Check if discount was found
752
                    if ($result > 0) {
753
                        // Check if discount not already affected to another invoice
754
                        if ($discount->fk_facture_line > 0) {
755
                            if (empty($noerrorifdiscountalreadylinked)) {
756
                                $this->error = $langs->trans("ErrorDiscountAlreadyUsed", $discount->id);
757
                                dol_syslog(get_class($this) . "::insert Error " . $this->error, LOG_ERR);
758
                                $this->db->rollback();
759
                                return -3;
760
                            }
761
                        } else {
762
                            $result = $discount->link_to_invoice($this->id, 0);
763
                            if ($result < 0) {
764
                                $this->error = $discount->error;
765
                                dol_syslog(get_class($this) . "::insert Error " . $this->error, LOG_ERR);
766
                                $this->db->rollback();
767
                                return -3;
768
                            }
769
                        }
770
                    } else {
771
                        $this->error = $langs->trans("ErrorADiscountThatHasBeenRemovedIsIncluded");
772
                        dol_syslog(get_class($this) . "::insert Error " . $this->error, LOG_ERR);
773
                        $this->db->rollback();
774
                        return -3;
775
                    }
776
                } else {
777
                    $this->error = $discount->error;
778
                    dol_syslog(get_class($this) . "::insert Error " . $this->error, LOG_ERR);
779
                    $this->db->rollback();
780
                    return -3;
781
                }
782
            }
783
784
            if (!$error && !$notrigger) {
785
                // Call trigger
786
                $result = $this->call_trigger('LINEBILL_SUPPLIER_CREATE', $user);
787
                if ($result < 0) {
788
                    $this->db->rollback();
789
                    return -2;
790
                }
791
                // End call triggers
792
            }
793
794
            $this->db->commit();
795
            return $this->id;
796
        } else {
797
            $this->error = $this->db->error();
798
            $this->db->rollback();
799
            return -2;
800
        }
801
    }
802
803
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
804
    /**
805
     *  Mise a jour de l'objet ligne de commande en base
806
     *
807
     *  @return     int     Return integer <0 si ko, >0 si ok
808
     */
809
    public function update_total()
810
    {
811
		// phpcs:enable
812
        $this->db->begin();
813
814
        // Mise a jour ligne en base
815
        $sql = "UPDATE " . MAIN_DB_PREFIX . "facture_fourn_det SET";
816
        $sql .= "  total_ht = " . price2num($this->total_ht);
817
        $sql .= ", tva= " . price2num($this->total_tva);
818
        $sql .= ", total_localtax1 = " . price2num($this->total_localtax1);
819
        $sql .= ", total_localtax2 = " . price2num($this->total_localtax2);
820
        $sql .= ", total_ttc = " . price2num($this->total_ttc);
821
        $sql .= " WHERE rowid = " . ((int) $this->id);
822
823
        dol_syslog("FactureFournisseurLigne.class.php::update_total", LOG_DEBUG);
824
825
        $resql = $this->db->query($sql);
826
        if ($resql) {
827
            $this->db->commit();
828
            return 1;
829
        } else {
830
            $this->error = $this->db->error();
831
            $this->db->rollback();
832
            return -2;
833
        }
834
    }
835
}
836