Passed
Branch develop (5cbde9)
by
unknown
26:38
created

FactureFournisseur::create()   F

Complexity

Conditions 49
Paths > 20000

Size

Total Lines 276
Code Lines 180

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 49
eloc 180
c 1
b 0
f 0
nc 5906432
nop 1
dl 0
loc 276
rs 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/* Copyright (C) 2002-2004	Rodolphe Quiedeville	<[email protected]>
3
 * Copyright (C) 2004-2012	Laurent Destailleur		<[email protected]>
4
 * Copyright (C) 2004		Christophe Combelles	<[email protected]>
5
 * Copyright (C) 2005		Marc Barilley			<[email protected]>
6
 * Copyright (C) 2005-2012	Regis Houssin			<[email protected]>
7
 * Copyright (C) 2010-2017	Juanjo Menent			<[email protected]>
8
 * Copyright (C) 2013-2019	Philippe Grand			<[email protected]>
9
 * Copyright (C) 2013		Florian Henry			<[email protected]>
10
 * Copyright (C) 2014-2016	Marcos García			<[email protected]>
11
 * Copyright (C) 2015		Bahfir Abbes			<[email protected]>
12
 * Copyright (C) 2015-2019	Ferran Marcet			<[email protected]>
13
 * Copyright (C) 2016		Alexandre Spangaro		<[email protected]>
14
 * Copyright (C) 2018       Nicolas ZABOURI			<[email protected]>
15
 * Copyright (C) 2018       Frédéric France         <[email protected]>
16
 *
17
 * This program is free software; you can redistribute it and/or modify
18
 * it under the terms of the GNU General Public License as published by
19
 * the Free Software Foundation; either version 3 of the License, or
20
 * (at your option) any later version.
21
 *
22
 * This program is distributed in the hope that it will be useful,
23
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25
 * GNU General Public License for more details.
26
 *
27
 * You should have received a copy of the GNU General Public License
28
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
29
 */
30
31
/**
32
 *  \file       htdocs/fourn/class/fournisseur.facture.class.php
33
 *  \ingroup    fournisseur,facture
34
 *  \brief      File of class to manage suppliers invoices
35
 */
36
37
include_once DOL_DOCUMENT_ROOT.'/core/class/commoninvoice.class.php';
38
require_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php';
39
40
/**
41
 *	Class to manage suppliers invoices
42
 */
43
class FactureFournisseur extends CommonInvoice
44
{
45
    /**
46
	 * @var string ID to identify managed object
47
	 */
48
	public $element='invoice_supplier';
49
50
    /**
51
     * @var string Name of table without prefix where object is stored
52
     */
53
    public $table_element='facture_fourn';
54
55
    /**
56
     * @var int    Name of subtable line
57
     */
58
    public $table_element_line='facture_fourn_det';
59
60
    /**
61
     * @var int Field with ID of parent key if this field has a parent
62
     */
63
    public $fk_element='fk_facture_fourn';
64
65
    public $picto='bill';
66
67
    /**
68
     * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
69
     * @var int
70
     */
71
    public $ismultientitymanaged = 1;
72
73
    /**
74
     * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user
75
     * @var integer
76
     */
77
    public $restrictiononfksoc = 1;
78
79
    /**
80
     * {@inheritdoc}
81
     */
82
    protected $table_ref_field = 'ref';
83
84
    /**
85
	 * @var int ID
86
	 */
87
	public $rowid;
88
89
    /**
90
	 * @var string Ref
91
	 */
92
	public $ref;
93
94
	public $label;
95
	public $libelle;		// @deprecated
96
97
    public $product_ref;
98
    public $ref_supplier;
99
    public $socid;
100
    //Check constants for types
101
    public $type = self::TYPE_STANDARD;
102
103
	/**
104
	 * Supplier invoice status
105
	 * @var int
106
	 * @see FactureFournisseur::STATUS_DRAFT, FactureFournisseur::STATUS_VALIDATED, FactureFournisseur::STATUS_PAID, FactureFournisseur::STATUS_ABANDONED
107
	 */
108
    public $statut;
109
110
    /**
111
     * Set to 1 if the invoice is completely paid, otherwise is 0
112
     * @var int
113
     * @deprecated Use statuses stored in self::statut
114
     */
115
    public $paye;
116
117
    public $author;
118
119
    /**
120
     * Date creation record (datec)
121
     *
122
     * @var integer
123
     */
124
    public $datec;
125
126
    /**
127
     * Date modification record (tms)
128
     *
129
     * @var integer
130
     */
131
    public $tms;
132
133
    /**
134
     * Invoice date (date)
135
     *
136
     * @var integer
137
     */
138
    public $date;
139
140
    /**
141
     * Max payment date (date_echeance)
142
     *
143
     * @var integer
144
     */
145
    public $date_echeance;
146
147
    public $amount=0;
148
    public $remise=0;
149
    public $tva=0;
150
    public $localtax1;
151
    public $localtax2;
152
    public $total_ht=0;
153
    public $total_tva=0;
154
    public $total_localtax1=0;
155
    public $total_localtax2=0;
156
    public $total_ttc=0;
157
158
	/**
159
	 * @deprecated
160
	 * @see $note_private, $note_public
161
	 */
162
    public $note;
163
164
    public $note_private;
165
    public $note_public;
166
    public $propalid;
167
    public $cond_reglement_id;
168
    public $cond_reglement_code;
169
170
    /**
171
     * @var int ID
172
     */
173
    public $fk_account;
174
175
    public $mode_reglement_id;
176
    public $mode_reglement_code;
177
178
	/**
179
	 * Invoice lines
180
	 * @var SupplierInvoiceLine[]
181
	 */
182
    public $lines = array();
183
184
	/**
185
	 * @deprecated
186
	 */
187
    public $fournisseur;
188
189
	/**
190
     * @var int ID Incorterms
191
     */
192
    public $fk_incoterms;
193
194
    public $location_incoterms;
195
    public $label_incoterms;  //Used into tooltip
196
197
    public $extraparams=array();
198
199
	// Multicurrency
200
	/**
201
     * @var int ID
202
     */
203
    public $fk_multicurrency;
204
205
    public $multicurrency_code;
206
    public $multicurrency_tx;
207
    public $multicurrency_total_ht;
208
    public $multicurrency_total_tva;
209
    public $multicurrency_total_ttc;
210
    //! id of source var_dump($$this);invoice if replacement invoice or credit note
211
    /**
212
     * @var int ID
213
     */
214
    public $fk_facture_source;
215
216
    /**
217
     * Standard invoice
218
     */
219
    const TYPE_STANDARD = 0;
220
221
    /**
222
     * Replacement invoice
223
     */
224
    const TYPE_REPLACEMENT = 1;
225
226
    /**
227
     * Credit note invoice
228
     */
229
    const TYPE_CREDIT_NOTE = 2;
230
231
    /**
232
     * Deposit invoice
233
     */
234
    const TYPE_DEPOSIT = 3;
235
236
    /**
237
     * Draft
238
     */
239
    const STATUS_DRAFT = 0;
240
241
    /**
242
     * Validated (need to be paid)
243
     */
244
    const STATUS_VALIDATED = 1;
245
246
    /**
247
     * Classified paid.
248
     * If paid partially, $this->close_code can be:
249
     * - CLOSECODE_DISCOUNTVAT
250
     * - CLOSECODE_BADDEBT
251
     * If paid completelly, this->close_code will be null
252
     */
253
    const STATUS_CLOSED = 2;
254
255
    /**
256
     * Classified abandoned and no payment done.
257
     * $this->close_code can be:
258
     * - CLOSECODE_BADDEBT
259
     * - CLOSECODE_ABANDONED
260
     * - CLOSECODE_REPLACED
261
     */
262
    const STATUS_ABANDONED = 3;
263
264
	const CLOSECODE_DISCOUNTVAT = 'discount_vat';
265
	const CLOSECODE_BADCREDIT = 'badsupplier';
266
	const CLOSECODE_ABANDONED = 'abandon';
267
	const CLOSECODE_REPLACED = 'replaced';
268
269
    /**
270
	 *	Constructor
271
	 *
272
	 *  @param		DoliDB		$db      Database handler
273
     */
274
    public function __construct($db)
275
    {
276
        $this->db = $db;
277
278
        $this->products = array();
279
    }
280
281
    /**
282
     *    Create supplier invoice into database
283
     *
284
     *    @param      User		$user       object utilisateur qui cree
285
     *    @return     int    	     		Id invoice created if OK, < 0 if KO
286
     */
287
    public function create($user)
288
    {
289
        global $langs,$conf,$hookmanager;
290
291
		$error=0;
292
        $now=dol_now();
293
294
        // Clean parameters
295
        if (isset($this->ref_supplier)) $this->ref_supplier=trim($this->ref_supplier);
296
        if (empty($this->type)) $this->type = self::TYPE_STANDARD;
297
        if (empty($this->date)) $this->date=$now;
298
299
        $socid = $this->socid;
300
        $ref_supplier = $this->ref_supplier;
301
        $amount = $this->amount;
302
        $remise = $this->remise;
303
304
		// Multicurrency (test on $this->multicurrency_tx because we should take the default rate only if not using origin rate)
305
		if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) list($this->fk_multicurrency,$this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code);
306
		else $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code);
307
		if (empty($this->fk_multicurrency))
308
		{
309
			$this->multicurrency_code = $conf->currency;
310
			$this->fk_multicurrency = 0;
311
			$this->multicurrency_tx = 1;
312
		}
313
314
        $this->db->begin();
315
316
        if (! $remise) $remise = 0 ;
317
318
        $sql = "INSERT INTO ".MAIN_DB_PREFIX."facture_fourn (";
319
		$sql.= "ref";
320
        $sql.= ", ref_supplier";
321
        $sql.= ", entity";
322
        $sql.= ", type";
323
        $sql.= ", libelle";
324
        $sql.= ", fk_soc";
325
        $sql.= ", datec";
326
        $sql.= ", datef";
327
		$sql.= ", fk_projet";
328
		$sql.= ", fk_cond_reglement";
329
		$sql.= ", fk_mode_reglement";
330
        $sql.= ", fk_account";
331
        $sql.= ", note_private";
332
        $sql.= ", note_public";
333
        $sql.= ", fk_user_author";
334
        $sql.= ", date_lim_reglement";
335
		$sql.= ", fk_incoterms, location_incoterms";
336
        $sql.= ", fk_multicurrency";
337
        $sql.= ", multicurrency_code";
338
        $sql.= ", multicurrency_tx";
339
        $sql.= ", fk_facture_source";
340
        $sql.= ")";
341
        $sql.= " VALUES (";
342
		$sql.= "'(PROV)'";
343
        $sql.= ", '".$this->db->escape($this->ref_supplier)."'";
344
        $sql.= ", ".$conf->entity;
345
        $sql.= ", '".$this->db->escape($this->type)."'";
346
        $sql.= ", '".$this->db->escape($this->label?$this->label:$this->libelle)."'";
347
        $sql.= ", ".$this->socid;
348
        $sql.= ", '".$this->db->idate($now)."'";
349
        $sql.= ", '".$this->db->idate($this->date)."'";
350
		$sql.= ", ".($this->fk_project > 0 ? $this->fk_project:"null");
351
		$sql.= ", ".($this->cond_reglement_id > 0 ? $this->cond_reglement_id:"null");
352
		$sql.= ", ".($this->mode_reglement_id > 0 ? $this->mode_reglement_id:"null");
353
        $sql.= ", ".($this->fk_account>0?$this->fk_account:'NULL');
354
        $sql.= ", '".$this->db->escape($this->note_private)."'";
355
        $sql.= ", '".$this->db->escape($this->note_public)."'";
356
        $sql.= ", ".$user->id.",";
357
        $sql.= $this->date_echeance!=''?"'".$this->db->idate($this->date_echeance)."'":"null";
358
		$sql.= ", ".(int) $this->fk_incoterms;
359
        $sql.= ", '".$this->db->escape($this->location_incoterms)."'";
360
		$sql.= ", ".(int) $this->fk_multicurrency;
361
		$sql.= ", '".$this->db->escape($this->multicurrency_code)."'";
362
		$sql.= ", ".(double) $this->multicurrency_tx;
363
        $sql.= ", ".(isset($this->fk_facture_source)?$this->fk_facture_source:"NULL");
364
        $sql.= ")";
365
366
        dol_syslog(get_class($this)."::create", LOG_DEBUG);
367
        $resql=$this->db->query($sql);
368
        if ($resql)
369
        {
370
            $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'facture_fourn');
371
372
            // Update ref with new one
373
            $this->ref='(PROV'.$this->id.')';
374
            $sql = 'UPDATE '.MAIN_DB_PREFIX."facture_fourn SET ref='".$this->db->escape($this->ref)."' WHERE rowid=".$this->id;
375
376
            dol_syslog(get_class($this)."::create", LOG_DEBUG);
377
            $resql=$this->db->query($sql);
378
            if (! $resql) $error++;
379
380
        	if (! empty($this->linkedObjectsIds) && empty($this->linked_objects))	// To use new linkedObjectsIds instead of old linked_objects
381
			{
382
				$this->linked_objects = $this->linkedObjectsIds;	// TODO Replace linked_objects with linkedObjectsIds
383
			}
384
385
			// Add object linked
386
			if (! $error && $this->id && is_array($this->linked_objects) && ! empty($this->linked_objects))
387
			{
388
				foreach($this->linked_objects as $origin => $tmp_origin_id)
389
				{
390
				    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, ...))
391
				    {
392
				        foreach($tmp_origin_id as $origin_id)
393
				        {
394
				            $ret = $this->add_object_linked($origin, $origin_id);
395
				            if (! $ret)
396
				            {
397
				                dol_print_error($this->db);
398
				                $error++;
399
				            }
400
				        }
401
				    }
402
				    else                                // Old behaviour, if linked_object has only one link per type, so is something like array('contract'=>id1))
403
				    {
404
				        $origin_id = $tmp_origin_id;
405
    					$ret = $this->add_object_linked($origin, $origin_id);
406
    					if (! $ret)
407
    					{
408
    						dol_print_error($this->db);
409
    						$error++;
410
    					}
411
				    }
412
				}
413
			}
414
415
			// Add linked object (deprecated, use ->linkedObjectsIds instead)
416
            if (! $error && $this->id && ! empty($this->origin) && ! empty($this->origin_id))
417
            {
418
                $ret = $this->add_object_linked();
419
                if (! $ret)
420
                {
421
                    dol_print_error($this->db);
422
                    $error++;
423
                }
424
            }
425
426
			if (count($this->lines) && is_object($this->lines[0]))	// If this->lines is array of InvoiceLines (preferred mode)
427
			{
428
				dol_syslog("There is ".count($this->lines)." lines that are invoice lines objects");
429
                foreach ($this->lines as $i => $val)
430
                {
431
                    $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'facture_fourn_det (fk_facture_fourn, special_code)';
432
                    $sql .= ' VALUES ('.$this->id.','.intval($this->lines[$i]->special_code).')';
433
434
                    $resql_insert=$this->db->query($sql);
435
                    if ($resql_insert)
436
                    {
437
                        $idligne = $this->db->last_insert_id(MAIN_DB_PREFIX.'facture_fourn_det');
438
439
                        $this->updateline(
440
                            $idligne,
441
                            $this->lines[$i]->description,
442
                            $this->lines[$i]->pu_ht,
1 ignored issue
show
Deprecated Code introduced by
The property SupplierInvoiceLine::$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

442
                            /** @scrutinizer ignore-deprecated */ $this->lines[$i]->pu_ht,

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...
443
                            $this->lines[$i]->tva_tx,
444
                            $this->lines[$i]->localtax1_tx,
445
                            $this->lines[$i]->localtax2_tx,
446
                            $this->lines[$i]->qty,
447
                            $this->lines[$i]->fk_product,
448
                            'HT',
449
                            (! empty($this->lines[$i]->info_bits)?$this->lines[$i]->info_bits:''),
450
                            $this->lines[$i]->product_type,
451
                            $this->lines[$i]->remise_percent,
452
                            false,
453
                            $this->lines[$i]->date_start,
454
                            $this->lines[$i]->date_end,
455
                            $this->lines[$i]->array_options,
456
                            $this->lines[$i]->fk_unit,
457
                            $this->lines[$i]->pu_ht_devise
0 ignored issues
show
Bug introduced by
The property pu_ht_devise does not seem to exist on SupplierInvoiceLine.
Loading history...
458
                        );
459
                    }
460
                    else
461
                    {
462
                        $this->error=$this->db->lasterror();
463
                        $this->db->rollback();
464
                        return -5;
465
                    }
466
                }
467
			}
468
			else	// If this->lines is an array of invoice line arrays
469
			{
470
			    dol_syslog("There is ".count($this->lines)." lines that are array lines");
471
			    foreach ($this->lines as $i => $val)
472
			    {
473
                	$line = $this->lines[$i];
474
475
                	// Test and convert into object this->lines[$i]. When coming from REST API, we may still have an array
476
				    //if (! is_object($line)) $line=json_decode(json_encode($line), false);  // convert recursively array into object.
477
                	if (! is_object($line)) $line = (object) $line;
478
479
                	$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'facture_fourn_det (fk_facture_fourn, special_code)';
480
			        $sql .= ' VALUES ('.$this->id.','.intval($this->lines[$i]->special_code).')';
481
482
			        $resql_insert=$this->db->query($sql);
483
			        if ($resql_insert)
484
			        {
485
			            $idligne = $this->db->last_insert_id(MAIN_DB_PREFIX.'facture_fourn_det');
486
487
            			$this->updateline(
488
			                $idligne,
489
			                $line->description,
490
			                $line->pu_ht,
491
			                $line->tva_tx,
492
			                $line->localtax1_tx,
493
			                $line->localtax2_tx,
494
			                $line->qty,
495
			                $line->fk_product,
496
			                'HT',
497
			                (! empty($line->info_bits)?$line->info_bits:''),
498
			                $line->product_type
499
			                );
500
			        }
501
			        else
502
			        {
503
			            $this->error=$this->db->lasterror();
504
			            $this->db->rollback();
505
			            return -5;
506
			        }
507
			    }
508
			}
509
510
            // Update total price
511
            $result=$this->update_price();
512
            if ($result > 0)
513
            {
514
				// Actions on extra fields
515
            	if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
516
				{
517
					$result=$this->insertExtraFields();               // This also set $this->error or $this->errors if errors are found
518
					if ($result < 0)
519
					{
520
						$error++;
521
					}
522
				}
523
524
				if (! $error)
525
				{
526
                    // Call trigger
527
                    $result=$this->call_trigger('BILL_SUPPLIER_CREATE', $user);
528
                    if ($result < 0) $error++;
529
                    // End call triggers
530
				}
531
532
                if (! $error)
533
                {
534
                    $this->db->commit();
535
                    return $this->id;
536
                }
537
                else
538
                {
539
                    $this->db->rollback();
540
                    return -4;
541
                }
542
            }
543
            else
544
            {
545
                $this->error=$langs->trans('FailedToUpdatePrice');
546
                $this->db->rollback();
547
                return -3;
548
            }
549
        }
550
        else
551
        {
552
            if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS')
553
            {
554
                $this->error=$langs->trans('ErrorRefAlreadyExists');
555
                $this->db->rollback();
556
                return -1;
557
            }
558
            else
559
            {
560
                $this->error=$this->db->lasterror();
561
                $this->db->rollback();
562
                return -2;
563
            }
564
        }
565
    }
566
567
    /**
568
     *    Load object in memory from database
569
     *
570
     *    @param	int		$id         Id supplier invoice
571
     *    @param	string	$ref		Ref supplier invoice
572
     *    @return   int        			<0 if KO, >0 if OK, 0 if not found
573
     */
574
    public function fetch($id = '', $ref = '')
575
    {
576
        global $langs;
577
578
        $sql = "SELECT";
579
        $sql.= " t.rowid,";
580
		$sql.= " t.ref,";
581
        $sql.= " t.ref_supplier,";
582
        $sql.= " t.entity,";
583
        $sql.= " t.type,";
584
        $sql.= " t.fk_soc,";
585
        $sql.= " t.datec,";
586
        $sql.= " t.datef,";
587
        $sql.= " t.tms,";
588
        $sql.= " t.libelle as label,";
589
        $sql.= " t.paye,";
590
        $sql.= " t.amount,";
591
        $sql.= " t.remise,";
592
        $sql.= " t.close_code,";
593
        $sql.= " t.close_note,";
594
        $sql.= " t.tva,";
595
        $sql.= " t.localtax1,";
596
        $sql.= " t.localtax2,";
597
        $sql.= " t.total_ht,";
598
        $sql.= " t.total_tva,";
599
        $sql.= " t.total_ttc,";
600
        $sql.= " t.fk_statut,";
601
        $sql.= " t.fk_user_author,";
602
        $sql.= " t.fk_user_valid,";
603
        $sql.= " t.fk_facture_source,";
604
        $sql.= " t.fk_projet as fk_project,";
605
        $sql.= " t.fk_cond_reglement,";
606
        $sql.= " t.fk_account,";
607
        $sql.= " t.fk_mode_reglement,";
608
        $sql.= " t.date_lim_reglement,";
609
        $sql.= " t.note_private,";
610
        $sql.= " t.note_public,";
611
        $sql.= " t.model_pdf,";
612
        $sql.= " t.import_key,";
613
        $sql.= " t.extraparams,";
614
        $sql.= " cr.code as cond_reglement_code, cr.libelle as cond_reglement_libelle,";
615
        $sql.= " p.code as mode_reglement_code, p.libelle as mode_reglement_libelle,";
616
        $sql.= ' s.nom as socnom, s.rowid as socid,';
617
        $sql.= ' t.fk_incoterms, t.location_incoterms,';
618
        $sql.= " i.libelle as label_incoterms,";
619
        $sql.= ' t.fk_multicurrency, t.multicurrency_code, t.multicurrency_tx, t.multicurrency_total_ht, t.multicurrency_total_tva, t.multicurrency_total_ttc';
620
        $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_fourn as t';
621
        $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON (t.fk_soc = s.rowid)";
622
        $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_payment_term as cr ON t.fk_cond_reglement = cr.rowid";
623
        $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as p ON t.fk_mode_reglement = p.id";
624
		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON t.fk_incoterms = i.rowid';
625
        if ($id)  $sql.= " WHERE t.rowid=".$id;
626
        if ($ref) $sql.= " WHERE t.ref='".$this->db->escape($ref)."' AND t.entity IN (".getEntity('supplier_invoice').")";
627
628
        dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
629
        $resql=$this->db->query($sql);
630
        if ($resql)
631
        {
632
            if ($this->db->num_rows($resql))
633
            {
634
                $obj = $this->db->fetch_object($resql);
635
636
                $this->id					= $obj->rowid;
637
                $this->ref					= $obj->ref?$obj->ref:$obj->rowid;	// We take rowid if ref is empty for backward compatibility
638
639
                $this->ref_supplier			= $obj->ref_supplier;
640
                $this->entity				= $obj->entity;
641
                $this->type					= empty($obj->type)? self::TYPE_STANDARD:$obj->type;
642
                $this->fk_soc				= $obj->fk_soc;
643
                $this->datec				= $this->db->jdate($obj->datec);
644
                $this->date					= $this->db->jdate($obj->datef);
645
                $this->datep				= $this->db->jdate($obj->datef);
646
                $this->tms					= $this->db->jdate($obj->tms);
647
                $this->libelle				= $obj->label;		// deprecated
648
                $this->label				= $obj->label;
649
                $this->paye					= $obj->paye;
650
                $this->amount				= $obj->amount;
651
                $this->remise				= $obj->remise;
652
                $this->close_code			= $obj->close_code;
653
                $this->close_note			= $obj->close_note;
654
                $this->tva					= $obj->tva;
655
                $this->total_localtax1		= $obj->localtax1;
656
                $this->total_localtax2		= $obj->localtax2;
657
                $this->total_ht				= $obj->total_ht;
658
                $this->total_tva			= $obj->total_tva;
659
                $this->total_ttc			= $obj->total_ttc;
660
                $this->fk_statut			= $obj->fk_statut;
661
                $this->statut				= $obj->fk_statut;
662
                $this->fk_user_author		= $obj->fk_user_author;
663
                $this->author				= $obj->fk_user_author;
664
                $this->fk_user_valid		= $obj->fk_user_valid;
665
                $this->fk_facture_source	= $obj->fk_facture_source;
666
                $this->fk_project			= $obj->fk_project;
667
                $this->cond_reglement_id	= $obj->fk_cond_reglement;
668
	            $this->cond_reglement_code	= $obj->cond_reglement_code;
669
	            $this->cond_reglement		= $obj->cond_reglement_libelle;
670
	            $this->cond_reglement_doc	= $obj->cond_reglement_libelle;
671
                $this->fk_account           = $obj->fk_account;
672
	            $this->mode_reglement_id	= $obj->fk_mode_reglement;
673
	            $this->mode_reglement_code	= $obj->mode_reglement_code;
674
	            $this->mode_reglement		= $obj->mode_reglement_libelle;
675
                $this->date_echeance		= $this->db->jdate($obj->date_lim_reglement);
676
                $this->note					= $obj->note_private;	// deprecated
677
                $this->note_private			= $obj->note_private;
678
                $this->note_public			= $obj->note_public;
679
                $this->model_pdf			= $obj->model_pdf;
680
                $this->modelpdf			    = $obj->model_pdf;
681
                $this->import_key			= $obj->import_key;
682
683
				//Incoterms
684
				$this->fk_incoterms = $obj->fk_incoterms;
685
				$this->location_incoterms = $obj->location_incoterms;
686
				$this->label_incoterms = $obj->label_incoterms;
687
688
				// Multicurrency
689
				$this->fk_multicurrency 		= $obj->fk_multicurrency;
690
				$this->multicurrency_code 		= $obj->multicurrency_code;
691
				$this->multicurrency_tx 		= $obj->multicurrency_tx;
692
				$this->multicurrency_total_ht 	= $obj->multicurrency_total_ht;
693
				$this->multicurrency_total_tva 	= $obj->multicurrency_total_tva;
694
				$this->multicurrency_total_ttc 	= $obj->multicurrency_total_ttc;
695
696
                $this->extraparams			= (array) json_decode($obj->extraparams, true);
697
698
                $this->socid  = $obj->socid;
699
                $this->socnom = $obj->socnom;
700
701
                // Retreive all extrafield
702
                // fetch optionals attributes and labels
703
                $this->fetch_optionals();
704
705
                if ($this->statut == self::STATUS_DRAFT) $this->brouillon = 1;
706
707
                $result=$this->fetch_lines();
708
                if ($result < 0)
709
                {
710
                    $this->error=$this->db->lasterror();
711
                    return -3;
712
                }
713
            }
714
            else
715
            {
716
                $this->error='Bill with id '.$id.' not found';
717
                dol_syslog(get_class($this).'::fetch '.$this->error);
718
                return 0;
719
            }
720
721
            $this->db->free($resql);
722
            return 1;
723
        }
724
        else
725
        {
726
            $this->error="Error ".$this->db->lasterror();
727
            return -1;
728
        }
729
    }
730
731
732
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
733
    /**
734
     *	Load this->lines
735
     *
736
     *  @return     int         1 si ok, < 0 si erreur
737
     */
738
    public function fetch_lines()
739
    {
740
        // phpcs:enable
741
        $this->lines = array();
742
743
        $sql = 'SELECT f.rowid, f.ref as ref_supplier, f.description, f.date_start, f.date_end, f.pu_ht, f.pu_ttc, f.qty, f.remise_percent, f.vat_src_code, f.tva_tx';
744
        $sql.= ', f.localtax1_tx, f.localtax2_tx, f.localtax1_type, f.localtax2_type, f.total_localtax1, f.total_localtax2, f.fk_facture_fourn ';
745
        $sql.= ', f.total_ht, f.tva as total_tva, f.total_ttc, f.fk_product, f.product_type, f.info_bits, f.rang, f.special_code, f.fk_parent_line, f.fk_unit';
746
        $sql.= ', p.rowid as product_id, p.ref as product_ref, p.label as label, p.description as product_desc';
747
        $sql.= ', f.fk_multicurrency, f.multicurrency_code, f.multicurrency_subprice, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc';
748
        $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_fourn_det as f';
749
        $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON f.fk_product = p.rowid';
750
        $sql.= ' WHERE fk_facture_fourn='.$this->id;
751
        $sql.= ' ORDER BY f.rang, f.rowid';
752
753
        dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG);
754
        $resql_rows = $this->db->query($sql);
755
        if ($resql_rows)
756
        {
757
            $num_rows = $this->db->num_rows($resql_rows);
758
            if ($num_rows)
759
            {
760
                $i = 0;
761
                while ($i < $num_rows)
762
                {
763
                    $obj = $this->db->fetch_object($resql_rows);
764
765
	                $line = new SupplierInvoiceLine($this->db);
766
767
                    $line->id				= $obj->rowid;
768
                    $line->rowid			= $obj->rowid;
769
                    $line->description		= $obj->description;
770
                    $line->date_start		= $obj->date_start;
771
                    $line->date_end			= $obj->date_end;
772
773
                    $line->product_ref		= $obj->product_ref;
774
                    $line->ref				= $obj->product_ref;
775
                    $line->ref_supplier		= $obj->ref_supplier;
776
                    $line->libelle			= $obj->label;
777
                    $line->label  			= $obj->label;
778
                    $line->product_desc		= $obj->product_desc;
779
                    $line->subprice			= $obj->pu_ht;
780
                    $line->pu_ht			= $obj->pu_ht;
781
                    $line->pu_ttc			= $obj->pu_ttc;
782
783
                    $line->vat_src_code     = $obj->vat_src_code;
784
                    $line->tva_tx			= $obj->tva_tx;
785
                    $line->localtax1_tx		= $obj->localtax1_tx;
786
                    $line->localtax2_tx		= $obj->localtax2_tx;
787
                    $line->localtax1_type	= $obj->localtax1_type;
788
                    $line->localtax2_type	= $obj->localtax2_type;
789
                    $line->qty				= $obj->qty;
790
                    $line->remise_percent   = $obj->remise_percent;
791
                    $line->tva				= $obj->total_tva;			// deprecated
792
                    $line->total_ht			= $obj->total_ht;
793
                    $line->total_ttc		= $obj->total_ttc;
794
                    $line->total_tva		= $obj->total_tva;
795
                    $line->total_localtax1	= $obj->total_localtax1;
796
                    $line->total_localtax2	= $obj->total_localtax2;
797
                    $line->fk_facture_fourn     = $obj->fk_facture_fourn;
798
                    $line->fk_product		= $obj->fk_product;
799
                    $line->product_type		= $obj->product_type;
800
                    $line->product_label	= $obj->label;
801
                    $line->info_bits		= $obj->info_bits;
802
                    $line->fk_parent_line   = $obj->fk_parent_line;
803
                    $line->special_code		= $obj->special_code;
804
                    $line->rang       		= $obj->rang;
805
                    $line->fk_unit          = $obj->fk_unit;
806
807
					// Multicurrency
808
					$line->fk_multicurrency = $obj->fk_multicurrency;
809
					$line->multicurrency_code = $obj->multicurrency_code;
810
					$line->multicurrency_subprice = $obj->multicurrency_subprice;
811
					$line->multicurrency_total_ht = $obj->multicurrency_total_ht;
812
					$line->multicurrency_total_tva = $obj->multicurrency_total_tva;
813
					$line->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
814
815
	                $this->lines[$i] = $line;
816
817
                    $i++;
818
                }
819
            }
820
            $this->db->free($resql_rows);
821
            return 1;
822
        }
823
        else
824
        {
825
            $this->error=$this->db->error();
826
            return -3;
827
        }
828
    }
829
830
831
    /**
832
     *  Update database
833
     *
834
     *  @param	User	$user            User that modify
835
     *  @param  int		$notrigger       0=launch triggers after, 1=disable triggers
836
     *  @return int 			         <0 if KO, >0 if OK
837
     */
838
    public function update($user = null, $notrigger = 0)
839
    {
840
        global $conf, $langs;
841
        $error=0;
842
843
        // Clean parameters
844
        if (empty($this->type)) $this->type= self::TYPE_STANDARD;
845
		if (isset($this->ref)) $this->ref=trim($this->ref);
846
        if (isset($this->ref_supplier)) $this->ref_supplier=trim($this->ref_supplier);
847
        if (isset($this->entity)) $this->entity=trim($this->entity);
848
        if (isset($this->type)) $this->type=trim($this->type);
849
        if (isset($this->fk_soc)) $this->fk_soc=trim($this->fk_soc);
850
        if (isset($this->label)) $this->label=trim($this->label);
851
        if (isset($this->libelle)) $this->libelle=trim($this->libelle);	// deprecated
852
        if (isset($this->paye)) $this->paye=trim($this->paye);
853
        if (isset($this->amount)) $this->amount=trim($this->amount);
854
        if (isset($this->remise)) $this->remise=trim($this->remise);
855
        if (isset($this->close_code)) $this->close_code=trim($this->close_code);
856
        if (isset($this->close_note)) $this->close_note=trim($this->close_note);
857
        if (isset($this->tva)) $this->tva=trim($this->tva);
858
        if (isset($this->localtax1)) $this->localtax1=trim($this->localtax1);
859
        if (isset($this->localtax2)) $this->localtax2=trim($this->localtax2);
860
        if (empty($this->total_ht)) $this->total_ht=0;
861
        if (empty($this->total_tva)) $this->total_tva=0;
862
        //	if (isset($this->total_localtax1)) $this->total_localtax1=trim($this->total_localtax1);
863
        //	if (isset($this->total_localtax2)) $this->total_localtax2=trim($this->total_localtax2);
864
        if (isset($this->total_ttc)) $this->total_ttc=trim($this->total_ttc);
865
        if (isset($this->statut)) $this->statut=(int) $this->statut;
866
        if (isset($this->author)) $this->author=trim($this->author);
867
        if (isset($this->fk_user_valid)) $this->fk_user_valid=trim($this->fk_user_valid);
868
        if (isset($this->fk_facture_source)) $this->fk_facture_source=trim($this->fk_facture_source);
869
        if (isset($this->fk_project)) $this->fk_project=trim($this->fk_project);
870
        if (isset($this->cond_reglement_id)) $this->cond_reglement_id=trim($this->cond_reglement_id);
871
        if (isset($this->note_private)) $this->note=trim($this->note_private);
872
        if (isset($this->note_public)) $this->note_public=trim($this->note_public);
873
        if (isset($this->model_pdf)) $this->model_pdf=trim($this->model_pdf);
874
        if (isset($this->import_key)) $this->import_key=trim($this->import_key);
875
876
877
        // Check parameters
878
        // Put here code to add control on parameters values
879
880
        // Update request
881
        $sql = "UPDATE ".MAIN_DB_PREFIX."facture_fourn SET";
882
		$sql.= " ref=".(isset($this->ref)?"'".$this->db->escape($this->ref)."'":"null").",";
883
        $sql.= " ref_supplier=".(isset($this->ref_supplier)?"'".$this->db->escape($this->ref_supplier)."'":"null").",";
884
        $sql.= " entity=".(isset($this->entity)?$this->entity:"null").",";
885
        $sql.= " type=".(isset($this->type)?$this->type:"null").",";
886
        $sql.= " fk_soc=".(isset($this->fk_soc)?$this->fk_soc:"null").",";
887
        $sql.= " datec=".(dol_strlen($this->datec)!=0 ? "'".$this->db->idate($this->datec)."'" : 'null').",";
888
        $sql.= " datef=".(dol_strlen($this->date)!=0 ? "'".$this->db->idate($this->date)."'" : 'null').",";
889
        if (dol_strlen($this->tms) != 0) $sql.= " tms=".(dol_strlen($this->tms)!=0 ? "'".$this->db->idate($this->tms)."'" : 'null').",";
890
        $sql.= " libelle=".(isset($this->label)?"'".$this->db->escape($this->label)."'":"null").",";
891
        $sql.= " paye=".(isset($this->paye)?$this->paye:"null").",";
892
        $sql.= " amount=".(isset($this->amount)?$this->amount:"null").",";
893
        $sql.= " remise=".(isset($this->remise)?$this->remise:"null").",";
894
        $sql.= " close_code=".(isset($this->close_code)?"'".$this->db->escape($this->close_code)."'":"null").",";
895
        $sql.= " close_note=".(isset($this->close_note)?"'".$this->db->escape($this->close_note)."'":"null").",";
896
        $sql.= " tva=".(isset($this->tva)?$this->tva:"null").",";
897
        $sql.= " localtax1=".(isset($this->localtax1)?$this->localtax1:"null").",";
898
        $sql.= " localtax2=".(isset($this->localtax2)?$this->localtax2:"null").",";
899
        $sql.= " total_ht=".(isset($this->total_ht)?$this->total_ht:"null").",";
900
        $sql.= " total_tva=".(isset($this->total_tva)?$this->total_tva:"null").",";
901
        $sql.= " total_ttc=".(isset($this->total_ttc)?$this->total_ttc:"null").",";
902
        $sql.= " fk_statut=".(isset($this->statut)?$this->statut:"null").",";
903
        $sql.= " fk_user_author=".(isset($this->author)?$this->author:"null").",";
904
        $sql.= " fk_user_valid=".(isset($this->fk_user_valid)?$this->fk_user_valid:"null").",";
905
        $sql.= " fk_facture_source=".(isset($this->fk_facture_source)?$this->fk_facture_source:"null").",";
906
        $sql.= " fk_projet=".(isset($this->fk_project)?$this->fk_project:"null").",";
907
        $sql.= " fk_cond_reglement=".(isset($this->cond_reglement_id)?$this->cond_reglement_id:"null").",";
908
        $sql.= " date_lim_reglement=".(dol_strlen($this->date_echeance)!=0 ? "'".$this->db->idate($this->date_echeance)."'" : 'null').",";
909
        $sql.= " note_private=".(isset($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null").",";
910
        $sql.= " note_public=".(isset($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null").",";
911
        $sql.= " model_pdf=".(isset($this->model_pdf)?"'".$this->db->escape($this->model_pdf)."'":"null").",";
912
        $sql.= " import_key=".(isset($this->import_key)?"'".$this->db->escape($this->import_key)."'":"null")."";
913
        $sql.= " WHERE rowid=".$this->id;
914
915
        $this->db->begin();
916
917
        dol_syslog(get_class($this)."::update", LOG_DEBUG);
918
        $resql = $this->db->query($sql);
919
920
        if (!$resql) {
921
            $error++;
922
923
            if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
924
                $this->errors[] = $langs->trans('ErrorRefAlreadyExists');
925
            } else {
926
                $this->errors[] = "Error ".$this->db->lasterror();
927
            }
928
        }
929
930
        if (! $error)
931
        {
932
            if (! $notrigger)
933
            {
934
                // Call trigger
935
                $result=$this->call_trigger('BILL_SUPPLIER_UPDATE', $user);
936
                if ($result < 0) $error++;
937
                // End call triggers
938
            }
939
        }
940
941
        // Commit or rollback
942
        if ($error)
943
        {
944
            foreach($this->errors as $errmsg)
945
            {
946
                dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
947
                $this->error.=($this->error?', '.$errmsg:$errmsg);
948
            }
949
            $this->db->rollback();
950
            return -1*$error;
951
        }
952
        else
953
        {
954
            $this->db->commit();
955
            return 1;
956
        }
957
    }
958
959
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
960
    /**
961
     *    Add a discount line into an invoice (as an invoice line) using an existing absolute discount (Consume the discount)
962
     *
963
     *    @param     int	$idremise	Id of absolute discount
964
     *    @return    int          		>0 if OK, <0 if KO
965
     */
966
    public function insert_discount($idremise)
967
    {
968
        // phpcs:enable
969
    	global $langs;
970
971
    	include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
972
    	include_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
973
974
    	$this->db->begin();
975
976
    	$remise=new DiscountAbsolute($this->db);
977
    	$result=$remise->fetch($idremise);
978
979
    	if ($result > 0)
980
    	{
981
    		if ($remise->fk_invoice_supplier)	// Protection against multiple submission
982
    		{
983
    			$this->error=$langs->trans("ErrorDiscountAlreadyUsed");
984
    			$this->db->rollback();
985
    			return -5;
986
    		}
987
988
    		$facligne=new SupplierInvoiceLine($this->db);
989
    		$facligne->fk_facture_fourn=$this->id;
990
    		$facligne->fk_remise_except=$remise->id;
0 ignored issues
show
Bug introduced by
The property fk_remise_except does not seem to exist on SupplierInvoiceLine.
Loading history...
991
    		$facligne->desc=$remise->description;   	// Description ligne
992
    		$facligne->vat_src_code=$remise->vat_src_code;
0 ignored issues
show
Bug introduced by
The property vat_src_code does not seem to exist on DiscountAbsolute.
Loading history...
Bug introduced by
The property vat_src_code does not seem to exist on SupplierInvoiceLine.
Loading history...
993
    		$facligne->tva_tx=$remise->tva_tx;
994
    		$facligne->subprice = -$remise->amount_ht;
995
    		$facligne->fk_product=0;					// Id produit predefini
996
    		$facligne->product_type=0;
997
    		$facligne->qty=1;
998
    		$facligne->remise_percent=0;
999
    		$facligne->rang=-1;
1000
    		$facligne->info_bits=2;
1001
1002
    		// Get buy/cost price of invoice that is source of discount
1003
    		if ($remise->fk_invoice_supplier_source > 0)
1004
    		{
1005
    			$srcinvoice=new FactureFournisseur($this->db);
1006
    			$srcinvoice->fetch($remise->fk_invoice_supplier_source);
1007
    			$totalcostpriceofinvoice=0;
1008
    			include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmargin.class.php';  // TODO Move this into commonobject
1009
    			$formmargin=new FormMargin($this->db);
1010
    			$arraytmp=$formmargin->getMarginInfosArray($srcinvoice, false);
1011
    			$facligne->pa_ht = $arraytmp['pa_total'];
1012
    		}
1013
1014
    		$facligne->total_ht  = -$remise->amount_ht;
1015
    		$facligne->total_tva = -$remise->amount_tva;
1016
    		$facligne->total_ttc = -$remise->amount_ttc;
1017
1018
    		$facligne->multicurrency_subprice = -$remise->multicurrency_subprice;
1019
    		$facligne->multicurrency_total_ht = -$remise->multicurrency_total_ht;
0 ignored issues
show
Bug introduced by
The property multicurrency_total_ht does not exist on DiscountAbsolute. Did you mean multicurrency_amount_ht?
Loading history...
1020
    		$facligne->multicurrency_total_tva = -$remise->multicurrency_total_tva;
0 ignored issues
show
Bug introduced by
The property multicurrency_total_tva does not exist on DiscountAbsolute. Did you mean multicurrency_amount_tva?
Loading history...
1021
    		$facligne->multicurrency_total_ttc = -$remise->multicurrency_total_ttc;
0 ignored issues
show
Bug introduced by
The property multicurrency_total_ttc does not exist on DiscountAbsolute. Did you mean multicurrency_amount_ttc?
Loading history...
1022
1023
    		$lineid=$facligne->insert();
1024
    		if ($lineid > 0)
1025
    		{
1026
    			$result=$this->update_price(1);
1027
    			if ($result > 0)
1028
    			{
1029
    				// Create link between discount and invoice line
1030
    				$result=$remise->link_to_invoice($lineid, 0, 'supplier');
1031
    				if ($result < 0)
1032
    				{
1033
    					$this->error=$remise->error;
1034
    					$this->db->rollback();
1035
    					return -4;
1036
    				}
1037
1038
    				$this->db->commit();
1039
    				return 1;
1040
    			}
1041
    			else
1042
    			{
1043
    				$this->error=$facligne->error;
1044
    				$this->db->rollback();
1045
    				return -1;
1046
    			}
1047
    		}
1048
    		else
1049
    		{
1050
    			$this->error=$facligne->error;
1051
    			$this->db->rollback();
1052
    			return -2;
1053
    		}
1054
    	}
1055
    	else
1056
    	{
1057
    		$this->db->rollback();
1058
    		return -3;
1059
    	}
1060
    }
1061
1062
1063
    /**
1064
     *	Delete invoice from database
1065
     *
1066
     *  @param      User	$user		    User object
1067
     *	@param	    int		$notrigger	    1=Does not execute triggers, 0= execute triggers
1068
     *	@return		int						<0 if KO, >0 if OK
1069
     */
1070
    public function delete(User $user, $notrigger = 0)
1071
    {
1072
        global $langs,$conf;
1073
1074
        $rowid=$this->id;
1075
1076
        dol_syslog("FactureFournisseur::delete rowid=".$rowid, LOG_DEBUG);
1077
1078
        // TODO Test if there is at least on payment. If yes, refuse to delete.
1079
1080
        $error=0;
1081
        $this->db->begin();
1082
1083
        if (! $error && ! $notrigger)
1084
        {
1085
            // Call trigger
1086
            $result=$this->call_trigger('BILL_SUPPLIER_DELETE', $user);
1087
            if ($result < 0)
1088
            {
1089
                $this->db->rollback();
1090
                return -1;
1091
            }
1092
            // Fin appel triggers
1093
        }
1094
1095
		if (! $error) {
1096
			// If invoice was converted into a discount not yet consumed, we remove discount
1097
			$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'societe_remise_except';
1098
			$sql .= ' WHERE fk_invoice_supplier_source = ' . $rowid;
1099
			$sql .= ' AND fk_invoice_supplier_line IS NULL';
1100
			$resql = $this->db->query($sql);
1101
1102
			// If invoice has consumned discounts
1103
			$this->fetch_lines();
1104
			$list_rowid_det = array ();
1105
			foreach ($this->lines as $key => $invoiceline) {
1106
				$list_rowid_det[] = $invoiceline->rowid;
1107
			}
1108
1109
			// Consumned discounts are freed
1110
			if (count($list_rowid_det)) {
1111
				$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'societe_remise_except';
1112
				$sql .= ' SET fk_invoice_supplier = NULL, fk_invoice_supplier_line = NULL';
1113
				$sql .= ' WHERE fk_invoice_supplier_line IN (' . join(',', $list_rowid_det) . ')';
1114
1115
				dol_syslog(get_class($this) . "::delete", LOG_DEBUG);
1116
				if (! $this->db->query($sql)) {
1117
					$error ++;
1118
				}
1119
			}
1120
		}
1121
1122
        if (! $error)
1123
        {
1124
            $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn_det WHERE fk_facture_fourn = '.$rowid.';';
1125
            dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1126
            $resql = $this->db->query($sql);
1127
            if ($resql)
1128
            {
1129
                $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn WHERE rowid = '.$rowid;
1130
                dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1131
                $resql2 = $this->db->query($sql);
1132
                if (! $resql2) {
1133
                	$error++;
1134
                }
1135
            }
1136
            else {
1137
            	$error++;
1138
            }
1139
        }
1140
1141
		if (! $error)
1142
		{
1143
			// Delete linked object
1144
			$res = $this->deleteObjectLinked();
1145
			if ($res < 0) $error++;
1146
		}
1147
1148
        if (! $error)
1149
        {
1150
        	// Delete linked object
1151
        	$res = $this->deleteObjectLinked();
1152
        	if ($res < 0) $error++;
1153
        }
1154
1155
        if (! $error)
1156
        {
1157
        	// We remove directory
1158
        	if ($conf->fournisseur->facture->dir_output)
1159
        	{
1160
        		include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1161
1162
        		$ref = dol_sanitizeFileName($this->ref);
1163
        		$dir = $conf->fournisseur->facture->dir_output.'/'.get_exdir($this->id, 2, 0, 0, $this, 'invoive_supplier').$ref;
1164
        		$file = $dir . "/" . $ref . ".pdf";
1165
        		if (file_exists($file))
1166
        		{
1167
        			if (! dol_delete_file($file, 0, 0, 0, $this)) // For triggers
1168
        			{
1169
        				$this->error='ErrorFailToDeleteFile';
1170
        				$error++;
1171
        			}
1172
        		}
1173
        		if (file_exists($dir))
1174
        		{
1175
        			$res=@dol_delete_dir_recursive($dir);
1176
1177
        			if (! $res)
1178
        			{
1179
        				$this->error='ErrorFailToDeleteDir';
1180
        				$error++;
1181
        			}
1182
        		}
1183
        	}
1184
        }
1185
1186
        // Remove extrafields
1187
        if ((! $error) && (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED))) // For avoid conflicts if trigger used
1188
        {
1189
        	$result=$this->deleteExtraFields();
1190
        	if ($result < 0)
1191
        	{
1192
        		$error++;
1193
        		dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR);
1194
        	}
1195
        }
1196
1197
        if (! $error)
1198
        {
1199
        	dol_syslog(get_class($this)."::delete $this->id by $user->id", LOG_DEBUG);
1200
        	$this->db->commit();
1201
        	return 1;
1202
        }
1203
        else
1204
        {
1205
        	$this->error=$this->db->lasterror();
1206
        	$this->db->rollback();
1207
        	return -$error;
1208
        }
1209
    }
1210
1211
1212
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1213
    /**
1214
     *  Tag invoice as a payed invoice
1215
     *
1216
     *	@param  User	$user       Object user
1217
     *	@param  string	$close_code	Code renseigne si on classe a payee completement alors que paiement incomplet. Not implementd yet.
1218
     *	@param  string	$close_note	Commentaire renseigne si on classe a payee alors que paiement incomplet. Not implementd yet.
1219
     *	@return int         		<0 si ko, >0 si ok
1220
     */
1221
    public function set_paid($user, $close_code = '', $close_note = '')
1222
    {
1223
        // phpcs:enable
1224
        global $conf,$langs;
1225
        $error=0;
1226
1227
        $this->db->begin();
1228
1229
        $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture_fourn';
1230
        $sql.= ' SET paye = 1, fk_statut=2';
1231
        $sql.= ' WHERE rowid = '.$this->id;
1232
1233
        dol_syslog("FactureFournisseur::set_paid", LOG_DEBUG);
1234
        $resql = $this->db->query($sql);
1235
        if ($resql)
1236
        {
1237
            // Call trigger
1238
            $result=$this->call_trigger('BILL_SUPPLIER_PAYED', $user);
1239
            if ($result < 0) $error++;
1240
            // End call triggers
1241
        }
1242
        else
1243
        {
1244
            $error++;
1245
            $this->error=$this->db->error();
1246
            dol_print_error($this->db);
1247
        }
1248
1249
        if (! $error)
1250
        {
1251
            $this->db->commit();
1252
            return 1;
1253
        }
1254
        else
1255
        {
1256
            $this->db->rollback();
1257
            return -1;
1258
        }
1259
    }
1260
1261
1262
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1263
    /**
1264
     *	Tag la facture comme non payee completement + appel trigger BILL_UNPAYED
1265
     *	Fonction utilisee quand un paiement prelevement est refuse,
1266
     *	ou quand une facture annulee et reouverte.
1267
     *
1268
     *	@param      User	$user       Object user that change status
1269
     *	@return     int         		<0 si ok, >0 si ok
1270
     */
1271
    public function set_unpaid($user)
1272
    {
1273
        // phpcs:enable
1274
        global $conf,$langs;
1275
        $error=0;
1276
1277
        $this->db->begin();
1278
1279
        $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture_fourn';
1280
        $sql.= ' SET paye=0, fk_statut=1, close_code=null, close_note=null';
1281
        $sql.= ' WHERE rowid = '.$this->id;
1282
1283
        dol_syslog("FactureFournisseur::set_unpaid", LOG_DEBUG);
1284
        $resql = $this->db->query($sql);
1285
        if ($resql)
1286
        {
1287
            // Call trigger
1288
            $result=$this->call_trigger('BILL_SUPPLIER_UNPAYED', $user);
1289
            if ($result < 0) $error++;
1290
            // End call triggers
1291
        }
1292
        else
1293
        {
1294
            $error++;
1295
            $this->error=$this->db->lasterror();
1296
            dol_syslog("FactureFournisseur::set_unpaid ".$this->error);
1297
        }
1298
1299
        if (! $error)
1300
        {
1301
            $this->db->commit();
1302
            return 1;
1303
        }
1304
        else
1305
        {
1306
            $this->db->rollback();
1307
            return -1;
1308
        }
1309
    }
1310
1311
    /**
1312
     *	Tag invoice as validated + call trigger BILL_VALIDATE
1313
     *
1314
     *	@param	User	$user           Object user that validate
1315
     *	@param  string	$force_number   Reference to force on invoice
1316
     *	@param	int		$idwarehouse	Id of warehouse for stock change
1317
     *  @param	int		$notrigger		1=Does not execute triggers, 0= execute triggers
1318
     *	@return int 			        <0 if KO, =0 if nothing to do, >0 if OK
1319
     */
1320
    public function validate($user, $force_number = '', $idwarehouse = 0, $notrigger = 0)
1321
    {
1322
        global $conf,$langs;
1323
1324
        require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1325
1326
        $now=dol_now();
1327
1328
        $error=0;
1329
        dol_syslog(get_class($this).'::validate user='.$user->id.', force_number='.$force_number.', idwarehouse='.$idwarehouse);
1330
1331
        // Force to have object complete for checks
1332
        $this->fetch_thirdparty();
1333
        $this->fetch_lines();
1334
1335
        // Check parameters
1336
        if ($this->statut > self::STATUS_DRAFT)	// This is to avoid to validate twice (avoid errors on logs and stock management)
1337
        {
1338
            dol_syslog(get_class($this)."::validate no draft status", LOG_WARNING);
1339
            return 0;
1340
        }
1341
        if (preg_match('/^'.preg_quote($langs->trans("CopyOf").' ').'/', $this->ref_supplier))
1342
        {
1343
        	$langs->load("errors");
1344
        	$this->error=$langs->trans("ErrorFieldFormat", $langs->transnoentities("RefSupplier")).'. '.$langs->trans('RemoveString', $langs->transnoentitiesnoconv("CopyOf"));
1345
            return -1;
1346
        }
1347
        if (count($this->lines) <= 0)
1348
        {
1349
        	$langs->load("errors");
1350
            $this->error=$langs->trans("ErrorObjectMustHaveLinesToBeValidated", $this->ref);
1351
            return -1;
1352
        }
1353
1354
        $this->db->begin();
1355
1356
        // Define new ref
1357
        if ($force_number)
1358
        {
1359
            $num = $force_number;
1360
        }
1361
        elseif (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref)) // empty should not happened, but when it occurs, the test save life
1362
        {
1363
            $num = $this->getNextNumRef($this->thirdparty);
1364
        }
1365
        else
1366
		{
1367
            $num = $this->ref;
1368
        }
1369
        $this->newref = $num;
1370
1371
        $sql = "UPDATE ".MAIN_DB_PREFIX."facture_fourn";
1372
        $sql.= " SET ref='".$num."', fk_statut = 1, fk_user_valid = ".$user->id.", date_valid = '".$this->db->idate($now)."'";
1373
        $sql.= " WHERE rowid = ".$this->id;
1374
1375
        dol_syslog(get_class($this)."::validate", LOG_DEBUG);
1376
        $resql = $this->db->query($sql);
1377
        if ($resql)
1378
        {
1379
            // Si on incrémente le produit principal et ses composants à la validation de facture fournisseur
1380
            if (! $error && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL))
1381
            {
1382
                require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
1383
                $langs->load("agenda");
1384
1385
                $cpt=count($this->lines);
1386
                for ($i = 0; $i < $cpt; $i++)
1387
                {
1388
                    if ($this->lines[$i]->fk_product > 0)
1389
                    {
1390
                        $this->line = $this->lines[$i];
1391
                        $mouvP = new MouvementStock($this->db);
1392
						$mouvP->origin = &$this;
1393
                        // We increase stock for product
1394
                        $up_ht_disc=$this->lines[$i]->pu_ht;
1395
                        if (! empty($this->lines[$i]->remise_percent) && empty($conf->global->STOCK_EXCLUDE_DISCOUNT_FOR_PMP)) $up_ht_disc=price2num($up_ht_disc * (100 - $this->lines[$i]->remise_percent) / 100, 'MU');
1396
                        if ($this->type == FactureFournisseur::TYPE_CREDIT_NOTE) $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $up_ht_disc, $langs->trans("InvoiceValidatedInDolibarr", $num));
1397
                        else $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $up_ht_disc, $langs->trans("InvoiceValidatedInDolibarr", $num));
1398
                        if ($result < 0) { $error++; }
1399
                        unset($this->line);
1400
                    }
1401
                }
1402
            }
1403
1404
            // Triggers call
1405
            if (! $error && empty($notrigger))
1406
            {
1407
                // Call trigger
1408
                $result=$this->call_trigger('BILL_SUPPLIER_VALIDATE', $user);
1409
                if ($result < 0) $error++;
1410
                // End call triggers
1411
            }
1412
1413
            if (! $error)
1414
            {
1415
	            $this->oldref = $this->ref;
1416
1417
            	// Rename directory if dir was a temporary ref
1418
            	if (preg_match('/^[\(]?PROV/i', $this->ref))
1419
            	{
1420
            		// Now we rename also files into index
1421
            		$sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref)+1).")), filepath = 'fournisseur/facture/".get_exdir($this->id, 2, 0, 0, $this, 'invoice_supplier').$this->db->escape($this->newref)."'";
1422
            		$sql.= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'fournisseur/facture/".get_exdir($this->id, 2, 0, 0, $this, 'invoice_supplier').$this->db->escape($this->ref)."' and entity = ".$conf->entity;
1423
            		$resql = $this->db->query($sql);
1424
            		if (! $resql) { $error++; $this->error = $this->db->lasterror(); }
1425
1426
            		// We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
1427
            		$oldref = dol_sanitizeFileName($this->ref);
1428
            		$newref = dol_sanitizeFileName($num);
1429
            		$dirsource = $conf->fournisseur->facture->dir_output.'/'.get_exdir($this->id, 2, 0, 0, $this, 'invoice_supplier').$oldref;
1430
            		$dirdest = $conf->fournisseur->facture->dir_output.'/'.get_exdir($this->id, 2, 0, 0, $this, 'invoice_supplier').$newref;
1431
            		if (! $error && file_exists($dirsource))
1432
            		{
1433
            			dol_syslog(get_class($this)."::validate rename dir ".$dirsource." into ".$dirdest);
1434
1435
            			if (@rename($dirsource, $dirdest))
1436
            			{
1437
            				dol_syslog("Rename ok");
1438
                            // Rename docs starting with $oldref with $newref
1439
	                        $listoffiles=dol_dir_list($conf->fournisseur->facture->dir_output.'/'.get_exdir($this->id, 2, 0, 0, $this, 'invoice_supplier').$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
1440
	                        foreach($listoffiles as $fileentry)
1441
	                        {
1442
	                        	$dirsource=$fileentry['name'];
1443
	                        	$dirdest=preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
1444
	                        	$dirsource=$fileentry['path'].'/'.$dirsource;
1445
	                        	$dirdest=$fileentry['path'].'/'.$dirdest;
1446
	                        	@rename($dirsource, $dirdest);
1 ignored issue
show
Security Best Practice introduced by
It seems like you do not handle an error condition for rename(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

1446
	                        	/** @scrutinizer ignore-unhandled */ @rename($dirsource, $dirdest);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1447
	                        }
1448
            			}
1449
            		}
1450
            	}
1451
            }
1452
1453
            // Set new ref and define current statut
1454
            if (! $error)
1455
            {
1456
            	$this->ref = $num;
1457
            	$this->statut=self::STATUS_VALIDATED;
1458
            	//$this->date_validation=$now; this is stored into log table
1459
            }
1460
1461
            if (! $error)
1462
            {
1463
                $this->db->commit();
1464
                return 1;
1465
            }
1466
            else
1467
            {
1468
                $this->db->rollback();
1469
                return -1;
1470
            }
1471
        }
1472
        else
1473
        {
1474
            $this->error=$this->db->error();
1475
            $this->db->rollback();
1476
            return -1;
1477
        }
1478
    }
1479
1480
    /**
1481
     *	Set draft status
1482
     *
1483
     *	@param	User	$user			Object user that modify
1484
     *	@param	int		$idwarehouse	Id warehouse to use for stock change.
1485
     *	@return	int						<0 if KO, >0 if OK
1486
     */
1487
    public function setDraft($user, $idwarehouse = -1)
1488
    {
1489
        // phpcs:enable
1490
        global $conf,$langs;
1491
1492
        $error=0;
1493
1494
        if ($this->statut == self::STATUS_DRAFT)
1495
        {
1496
            dol_syslog(__METHOD__." already draft status", LOG_WARNING);
1497
            return 0;
1498
        }
1499
1500
        dol_syslog(__METHOD__, LOG_DEBUG);
1501
1502
        $this->db->begin();
1503
1504
        $sql = "UPDATE ".MAIN_DB_PREFIX."facture_fourn";
1505
        $sql.= " SET fk_statut = ".self::STATUS_DRAFT;
1506
        $sql.= " WHERE rowid = ".$this->id;
1507
1508
        $result=$this->db->query($sql);
1509
        if ($result)
1510
        {
1511
            if (! $error)
1512
            {
1513
                $this->oldcopy= clone $this;
1514
            }
1515
1516
            // Si on incremente le produit principal et ses composants a la validation de facture fournisseur, on decremente
1517
            if ($result >= 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL))
1518
            {
1519
                require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
1520
                $langs->load("agenda");
1521
1522
                $cpt=count($this->lines);
1523
                for ($i = 0; $i < $cpt; $i++)
1524
                {
1525
                    if ($this->lines[$i]->fk_product > 0)
1526
                    {
1527
                        $mouvP = new MouvementStock($this->db);
1528
                        $mouvP->origin = &$this;
1529
						// We increase stock for product
1530
						if ($this->type == FactureFournisseur::TYPE_CREDIT_NOTE) $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceBackToDraftInDolibarr", $this->ref));
1531
                        else $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceBackToDraftInDolibarr", $this->ref));
1532
                    }
1533
                }
1534
            }
1535
            // Triggers call
1536
            if (! $error && empty($notrigger))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $notrigger seems to never exist and therefore empty should always be true.
Loading history...
1537
            {
1538
                // Call trigger
1539
                $result=$this->call_trigger('BILL_SUPPLIER_UNVALIDATE', $user);
1540
                if ($result < 0) $error++;
1541
                // End call triggers
1542
            }
1543
            if ($error == 0)
1544
            {
1545
                $this->db->commit();
1546
                return 1;
1547
            }
1548
            else
1549
            {
1550
                $this->db->rollback();
1551
                return -1;
1552
            }
1553
        }
1554
        else
1555
        {
1556
            $this->error=$this->db->error();
1557
            $this->db->rollback();
1558
            return -1;
1559
        }
1560
    }
1561
1562
1563
    /**
1564
     *	Ajoute une ligne de facture (associe a aucun produit/service predefini)
1565
     *	Les parametres sont deja cense etre juste et avec valeurs finales a l'appel
1566
     *	de cette methode. Aussi, pour le taux tva, il doit deja avoir ete defini
1567
     *	par l'appelant par la methode get_default_tva(societe_vendeuse,societe_acheteuse,idprod)
1568
     *	et le desc doit deja avoir la bonne valeur (a l'appelant de gerer le multilangue).
1569
     *
1570
     *	@param    	string	$desc            	Description de la ligne
1571
     *	@param    	double	$pu              	Prix unitaire (HT ou TTC selon price_base_type, > 0 even for credit note)
1572
     *	@param    	double	$txtva           	Force Vat rate to use, -1 for auto.
1573
     *	@param		double	$txlocaltax1		LocalTax1 Rate
1574
     *	@param		double	$txlocaltax2		LocalTax2 Rate
1575
     *	@param    	double	$qty             	Quantite
1576
     *	@param    	int		$fk_product      	Product/Service ID predefined
1577
     *	@param    	double	$remise_percent  	Percentage discount of the line
1578
     *	@param    	integer	$date_start      	Date de debut de validite du service
1579
     * 	@param    	integer	$date_end        	Date de fin de validite du service
1580
     * 	@param    	string	$ventil          	Code de ventilation comptable
1581
     *	@param    	int		$info_bits			Bits de type de lines
1582
     *	@param    	string	$price_base_type 	HT ou TTC
1583
     *	@param		int		$type				Type of line (0=product, 1=service)
1584
     *  @param      int		$rang            	Position of line
1585
     *  @param		int		$notrigger			Disable triggers
1586
	 *  @param		array	$array_options		extrafields array
1587
     * 	@param 		string	$fk_unit 			Code of the unit to use. Null to use the default one
1588
     *  @param      int     $origin_id          id origin document
1589
	 *  @param		double	$pu_ht_devise		Amount in currency
1590
	 *  @param		string	$ref_supplier		Supplier ref
1591
	 *  @param      string  $special_code       Special code
1592
     *	@return    	int             			>0 if OK, <0 if KO
1593
     */
1594
    public function addline($desc, $pu, $txtva, $txlocaltax1, $txlocaltax2, $qty, $fk_product = 0, $remise_percent = 0, $date_start = '', $date_end = '', $ventil = 0, $info_bits = '', $price_base_type = 'HT', $type = 0, $rang = -1, $notrigger = false, $array_options = 0, $fk_unit = null, $origin_id = 0, $pu_ht_devise = 0, $ref_supplier = '', $special_code = '')
1595
    {
1596
    	global $langs, $mysoc, $conf;
1597
1598
    	dol_syslog(get_class($this)."::addline $desc,$pu,$qty,$txtva,$fk_product,$remise_percent,$date_start,$date_end,$ventil,$info_bits,$price_base_type,$type,$fk_unit", LOG_DEBUG);
1599
        include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
1600
1601
		if ($this->statut == self::STATUS_DRAFT)
1602
		{
1603
			// Clean parameters
1604
			if (empty($remise_percent)) $remise_percent=0;
1605
			if (empty($qty)) $qty=0;
1606
			if (empty($info_bits)) $info_bits=0;
1607
			if (empty($rang)) $rang=0;
1608
			if (empty($ventil)) $ventil=0;
1609
			if (empty($txtva)) $txtva=0;
1610
			if (empty($txlocaltax1)) $txlocaltax1=0;
1611
			if (empty($txlocaltax2)) $txlocaltax2=0;
1612
1613
			$remise_percent=price2num($remise_percent);
1614
			$qty=price2num($qty);
1615
			$pu=price2num($pu);
1616
			$txlocaltax1=price2num($txlocaltax1);
1617
			$txlocaltax2=price2num($txlocaltax2);
1618
			if (!preg_match('/\((.*)\)/', $txtva)) {
1619
				$txtva = price2num($txtva);               // $txtva can have format '5,1' or '5.1' or '5.1(XXX)', we must clean only if '5,1'
1620
			}
1621
1622
			if ($date_start && $date_end && $date_start > $date_end) {
1623
				$langs->load("errors");
1624
				$this->error=$langs->trans('ErrorStartDateGreaterEnd');
1625
				return -1;
1626
			}
1627
1628
	        $this->db->begin();
1629
1630
	        if ($fk_product > 0)
1631
	        {
1632
	        	if (! empty($conf->global->SUPPLIER_INVOICE_WITH_PREDEFINED_PRICES_ONLY))
1633
	        	{
1634
	        		// Check quantity is enough
1635
	        		dol_syslog(get_class($this)."::addline we check supplier prices fk_product=".$fk_product." qty=".$qty." ref_supplier=".$ref_supplier);
1636
	        		$prod = new Product($this->db, $fk_product);
1 ignored issue
show
Unused Code introduced by
The call to Product::__construct() has too many arguments starting with $fk_product. ( Ignorable by Annotation )

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

1636
	        		$prod = /** @scrutinizer ignore-call */ new Product($this->db, $fk_product);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
1637
	        		if ($prod->fetch($fk_product) > 0)
1638
	        		{
1639
	        			$product_type = $prod->type;
1640
	        			$label = $prod->label;
1641
	        			$fk_prod_fourn_price = 0;
1642
1643
	        			// We use 'none' instead of $ref_supplier, because $ref_supplier may not exists anymore. So we will take the first supplier price ok.
1644
	        			// If we want a dedicated supplier price, we must provide $fk_prod_fourn_price.
1645
	        			$result=$prod->get_buyprice($fk_prod_fourn_price, $qty, $fk_product, 'none', ($this->fk_soc?$this->fk_soc:$this->socid));   // Search on couple $fk_prod_fourn_price/$qty first, then on triplet $qty/$fk_product/$ref_supplier/$this->fk_soc
1646
	        			if ($result > 0)
1647
	        			{
1648
	        				$pu = $prod->fourn_pu;       // Unit price supplier price set by get_buyprice
1649
	        				$ref_supplier = $prod->ref_supplier;   // Ref supplier price set by get_buyprice
1650
	        				// is remise percent not keyed but present for the product we add it
1651
	        				if ($remise_percent == 0 && $prod->remise_percent !=0)
1652
	        					$remise_percent =$prod->remise_percent;
1653
	        			}
1654
	        			if ($result == 0)                   // If result == 0, we failed to found the supplier reference price
1655
	        			{
1656
	        				$langs->load("errors");
1657
	        				$this->error = "Ref " . $prod->ref . " " . $langs->trans("ErrorQtyTooLowForThisSupplier");
1658
	        				$this->db->rollback();
1659
	        				dol_syslog(get_class($this)."::addline we did not found supplier price, so we can't guess unit price");
1660
	        				//$pu    = $prod->fourn_pu;     // We do not overwrite unit price
1661
	        				//$ref   = $prod->ref_fourn;    // We do not overwrite ref supplier price
1662
	        				return -1;
1663
	        			}
1664
	        			if ($result == -1)
1665
	        			{
1666
	        				$langs->load("errors");
1667
	        				$this->error = "Ref " . $prod->ref . " " . $langs->trans("ErrorQtyTooLowForThisSupplier");
1668
	        				$this->db->rollback();
1669
	        				dol_syslog(get_class($this)."::addline result=".$result." - ".$this->error, LOG_DEBUG);
1670
	        				return -1;
1671
	        			}
1672
	        			if ($result < -1)
1673
	        			{
1674
	        				$this->error=$prod->error;
1675
	        				$this->db->rollback();
1676
	        				dol_syslog(get_class($this)."::addline result=".$result." - ".$this->error, LOG_ERR);
1677
	        				return -1;
1678
	        			}
1679
	        		}
1680
	        		else
1681
	        		{
1682
	        			$this->error=$prod->error;
1683
	        			$this->db->rollback();
1684
	        			return -1;
1685
	        		}
1686
	        	}
1687
	        }
1688
	        else
1689
	        {
1690
	        	$product_type = $type;
1691
	        }
1692
1693
	        if ($conf->multicurrency->enabled && $pu_ht_devise > 0) {
1694
	        	$pu = 0;
1695
	        }
1696
1697
	        $localtaxes_type=getLocalTaxesFromRate($txtva, 0, $mysoc, $this->thirdparty);
1698
1699
	        // Clean vat code
1700
	        $vat_src_code='';
1701
	        if (preg_match('/\((.*)\)/', $txtva, $reg))
1702
	        {
1703
	        	$vat_src_code = $reg[1];
1704
	        	$txtva = preg_replace('/\s*\(.*\)/', '', $txtva);    // Remove code into vatrate.
1705
	        }
1706
1707
	        // Calcul du total TTC et de la TVA pour la ligne a partir de
1708
	        // qty, pu, remise_percent et txtva
1709
	        // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
1710
	        // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
1711
1712
	        $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $this->thirdparty, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise);
1713
	        $total_ht  = $tabprice[0];
1714
	        $total_tva = $tabprice[1];
1715
	        $total_ttc = $tabprice[2];
1716
	        $total_localtax1 = $tabprice[9];
1717
	        $total_localtax2 = $tabprice[10];
1718
			$pu_ht = $tabprice[3];
1719
1720
			// MultiCurrency
1721
			$multicurrency_total_ht  = $tabprice[16];
1722
			$multicurrency_total_tva = $tabprice[17];
1723
			$multicurrency_total_ttc = $tabprice[18];
1724
			$pu_ht_devise = $tabprice[19];
1725
1726
			// Check parameters
1727
			if ($type < 0) return -1;
1728
1729
			if ($rang < 0)
1730
			{
1731
				$rangmax = $this->line_max();
1732
				$rang = $rangmax + 1;
1733
			}
1734
1735
			// Insert line
1736
			$this->line=new SupplierInvoiceLine($this->db);
1737
1738
			$this->line->context = $this->context;
1739
1740
			$this->line->fk_facture_fourn=$this->id;
1741
			//$this->line->label=$label;	// deprecated
1742
			$this->line->desc=$desc;
1743
			$this->line->ref_supplier=$ref_supplier;
1744
1745
			$this->line->qty=            ($this->type==self::TYPE_CREDIT_NOTE?abs($qty):$qty);	     // For credit note, quantity is always positive and unit price negative
1746
			$this->line->subprice=       ($this->type==self::TYPE_CREDIT_NOTE?-abs($pu_ht):$pu_ht);  // For credit note, unit price always negative, always positive otherwise
1747
1748
			$this->line->vat_src_code=$vat_src_code;
0 ignored issues
show
Bug introduced by
The property vat_src_code does not seem to exist on SupplierInvoiceLine.
Loading history...
1749
			$this->line->tva_tx=$txtva;
1750
			$this->line->localtax1_tx=($total_localtax1?$localtaxes_type[1]:0);
1751
			$this->line->localtax2_tx=($total_localtax2?$localtaxes_type[3]:0);
1752
			$this->line->localtax1_type = $localtaxes_type[0];
1753
			$this->line->localtax2_type = $localtaxes_type[2];
1754
1755
			$this->line->total_ht=       (($this->type==self::TYPE_CREDIT_NOTE||$qty<0)?-abs($total_ht):$total_ht);  // For credit note and if qty is negative, total is negative
1756
			$this->line->total_tva=      (($this->type==self::TYPE_CREDIT_NOTE||$qty<0)?-abs($total_tva):$total_tva);
1757
			$this->line->total_localtax1=(($this->type==self::TYPE_CREDIT_NOTE||$qty<0)?-abs($total_localtax1):$total_localtax1);
1758
			$this->line->total_localtax2=(($this->type==self::TYPE_CREDIT_NOTE||$qty<0)?-abs($total_localtax2):$total_localtax2);
1759
			$this->line->total_ttc=      (($this->type==self::TYPE_CREDIT_NOTE||$qty<0)?-abs($total_ttc):$total_ttc);
1760
1761
			$this->line->fk_product=$fk_product;
1762
			$this->line->product_type=$type;
1763
			$this->line->remise_percent=$remise_percent;
1764
			$this->line->date_start=$date_start;
1765
			$this->line->date_end=$date_end;
1766
			$this->line->ventil=$ventil;
0 ignored issues
show
Bug introduced by
The property ventil does not seem to exist on SupplierInvoiceLine.
Loading history...
1767
			$this->line->rang=$rang;
1768
			$this->line->info_bits=$info_bits;
1769
1770
			$this->line->special_code=((string) $special_code != '' ? $special_code : $this->special_code);
1771
			$this->line->fk_parent_line=$this->fk_parent_line;
1772
			$this->line->origin=$this->origin;
1773
			$this->line->origin_id=$origin_id;
1774
			$this->line->fk_unit=$fk_unit;
1775
1776
			// Multicurrency
1777
			$this->line->fk_multicurrency			= $this->fk_multicurrency;
1778
			$this->line->multicurrency_code			= $this->multicurrency_code;
1779
			$this->line->multicurrency_subprice		= $pu_ht_devise;
1780
			$this->line->multicurrency_total_ht 	= $multicurrency_total_ht;
1781
			$this->line->multicurrency_total_tva 	= $multicurrency_total_tva;
1782
			$this->line->multicurrency_total_ttc 	= $multicurrency_total_ttc;
1783
1784
			if (is_array($array_options) && count($array_options)>0) {
1785
				$this->line->array_options=$array_options;
1786
			}
1787
1788
			$result=$this->line->insert($notrigger);
1789
			if ($result > 0)
1790
			{
1791
				// Reorder if child line
1792
				if (! empty($fk_parent_line)) $this->line_order(true, 'DESC');
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $fk_parent_line seems to never exist and therefore empty should always be true.
Loading history...
1793
1794
				// Mise a jour informations denormalisees au niveau de la facture meme
1795
				$result=$this->update_price(1, 'auto', 0, $this->thirdparty);	// The addline method is designed to add line from user input so total calculation with update_price must be done using 'auto' mode.
1796
				if ($result > 0)
1797
				{
1798
					$this->db->commit();
1799
					return $this->line->id;
1800
				}
1801
				else
1802
				{
1803
					$this->error=$this->db->error();
1804
					$this->db->rollback();
1805
					return -1;
1806
				}
1807
			}
1808
			else
1809
			{
1810
				$this->error=$this->line->error;
1811
				$this->errors=$this->line->errors;
1812
				$this->db->rollback();
1813
				return -2;
1814
			}
1815
        }
1816
        else
1817
        {
1818
        	return 0;
1819
        }
1820
    }
1821
1822
    /**
1823
     * Update a line detail into database
1824
     *
1825
     * @param     	int			$id            		Id of line invoice
1826
     * @param     	string		$desc         		Description of line
1827
     * @param     	double		$pu          		Prix unitaire (HT ou TTC selon price_base_type)
1828
     * @param     	double		$vatrate       		VAT Rate (Can be '8.5', '8.5 (ABC)')
1829
     * @param		double		$txlocaltax1		LocalTax1 Rate
1830
     * @param		double		$txlocaltax2		LocalTax2 Rate
1831
     * @param     	double		$qty           		Quantity
1832
     * @param     	int			$idproduct			Id produit
1833
     * @param	  	double		$price_base_type	HT or TTC
1834
     * @param	  	int			$info_bits			Miscellaneous informations of line
1835
     * @param		int			$type				Type of line (0=product, 1=service)
1836
     * @param     	double		$remise_percent  	Percentage discount of the line
1837
     * @param		int			$notrigger			Disable triggers
1838
     * @param      	integer 	$date_start     	Date start of service
1839
     * @param      	integer     $date_end       	Date end of service
1840
	 * @param		array		$array_options		extrafields array
1841
     * @param 		string		$fk_unit 			Code of the unit to use. Null to use the default one
1842
	 * @param		double		$pu_ht_devise		Amount in currency
1843
	 * @param		string		$ref_supplier		Supplier ref
1844
     * @return    	int           					<0 if KO, >0 if OK
1845
     */
1846
    public function updateline($id, $desc, $pu, $vatrate, $txlocaltax1 = 0, $txlocaltax2 = 0, $qty = 1, $idproduct = 0, $price_base_type = 'HT', $info_bits = 0, $type = 0, $remise_percent = 0, $notrigger = false, $date_start = '', $date_end = '', $array_options = 0, $fk_unit = null, $pu_ht_devise = 0, $ref_supplier = '')
1847
    {
1848
    	global $mysoc, $langs;
1849
        dol_syslog(get_class($this)."::updateline $id,$desc,$pu,$vatrate,$qty,$idproduct,$price_base_type,$info_bits,$type,$remise_percent,$notrigger,$date_start,$date_end,$fk_unit,$pu_ht_devise,$ref_supplier", LOG_DEBUG);
1850
        include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
1851
1852
        $pu = price2num($pu);
1853
        $qty  = price2num($qty);
1854
		$remise_percent=price2num($remise_percent);
1855
		$pu_ht_devise = price2num($pu_ht_devise);
1856
1857
        // Check parameters
1858
        //if (! is_numeric($pu) || ! is_numeric($qty)) return -1;
1859
        if ($type < 0) return -1;
1860
1861
        if ($date_start && $date_end && $date_start > $date_end) {
1862
            $langs->load("errors");
1863
            $this->error=$langs->trans('ErrorStartDateGreaterEnd');
1864
            return -1;
1865
        }
1866
1867
        // Clean parameters
1868
		if (empty($vatrate)) $vatrate=0;
1869
        if (empty($txlocaltax1)) $txlocaltax1=0;
1870
        if (empty($txlocaltax2)) $txlocaltax2=0;
1871
1872
        $txlocaltax1=price2num($txlocaltax1);
1873
        $txlocaltax2=price2num($txlocaltax2);
1874
1875
        $localtaxes_type = array($txlocaltax1,$txlocaltax2);
1876
1877
        // Calcul du total TTC et de la TVA pour la ligne a partir de
1878
        // qty, pu, remise_percent et txtva
1879
        // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
1880
        // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
1881
1882
        $localtaxes_type=getLocalTaxesFromRate($vatrate, 0, $mysoc, $this->thirdparty);
1883
1884
        // Clean vat code
1885
        $vat_src_code='';
1886
        if (preg_match('/\((.*)\)/', $vatrate, $reg))
1887
        {
1888
            $vat_src_code = $reg[1];
1889
            $vatrate = preg_replace('/\s*\(.*\)/', '', $vatrate);    // Remove code into vatrate.
1890
        }
1891
1892
        $tabprice = calcul_price_total($qty, $pu, $remise_percent, $vatrate, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $this->thirdparty, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise);
1893
        $total_ht  = $tabprice[0];
1894
        $total_tva = $tabprice[1];
1895
        $total_ttc = $tabprice[2];
1896
        $pu_ht  = $tabprice[3];
1897
        $pu_tva = $tabprice[4];
1898
        $pu_ttc = $tabprice[5];
1899
        $total_localtax1 = $tabprice[9];
1900
        $total_localtax2 = $tabprice[10];
1901
1902
		// MultiCurrency
1903
		$multicurrency_total_ht  = $tabprice[16];
1904
        $multicurrency_total_tva = $tabprice[17];
1905
        $multicurrency_total_ttc = $tabprice[18];
1906
		$pu_ht_devise = $tabprice[19];
1907
1908
        if (empty($info_bits)) $info_bits=0;
1909
1910
        if ($idproduct)
1911
        {
1912
            $product=new Product($this->db);
1913
            $result=$product->fetch($idproduct);
1914
            $product_type = $product->type;
1915
        }
1916
        else
1917
        {
1918
            $product_type = $type;
1919
        }
1920
1921
	    $line = new SupplierInvoiceLine($this->db);
1922
1923
	    if ($line->fetch($id) < 1) {
1924
		    return -1;
1925
	    }
1926
1927
	    $line->description = $desc;
1928
	    $line->subprice = $pu_ht;
1929
	    $line->pu_ht = $pu_ht;
1 ignored issue
show
Deprecated Code introduced by
The property SupplierInvoiceLine::$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

1929
	    /** @scrutinizer ignore-deprecated */ $line->pu_ht = $pu_ht;

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...
1930
	    $line->pu_ttc = $pu_ttc;
1931
	    $line->qty = $qty;
1932
	    $line->remise_percent = $remise_percent;
1933
	    $line->ref_supplier = $ref_supplier;
1934
1935
	    $line->date_start = $date_start;
1936
	    $line->date_end = $date_end;
1937
1938
	    $line->vat_src_code=$vat_src_code;
0 ignored issues
show
Bug introduced by
The property vat_src_code does not seem to exist on SupplierInvoiceLine.
Loading history...
1939
	    $line->tva_tx = $vatrate;
1940
	    $line->localtax1_tx = $txlocaltax1;
1941
	    $line->localtax2_tx = $txlocaltax2;
1942
		$line->localtax1_type = $localtaxes_type[0];
1943
		$line->localtax2_type = $localtaxes_type[2];
1944
		$line->total_ht = (($this->type==self::TYPE_CREDIT_NOTE||$qty<0)?-abs($total_ht):$total_ht);
1945
		$line->total_tva = (($this->type==self::TYPE_CREDIT_NOTE||$qty<0)?-abs($total_tva):$total_tva);
1946
	    $line->total_localtax1 = $total_localtax1;
1947
	    $line->total_localtax2 = $total_localtax2;
1948
	    $line->total_ttc = (($this->type==self::TYPE_CREDIT_NOTE||$qty<0)?-abs($total_ttc):$total_ttc);
1949
	    $line->fk_product = $idproduct;
1950
	    $line->product_type = $product_type;
1951
	    $line->info_bits = $info_bits;
1952
	    $line->fk_unit = $fk_unit;
1953
	    $line->array_options = $array_options;
1954
1955
		// Multicurrency
1956
		$line->multicurrency_subprice	= $pu_ht_devise;
1957
		$line->multicurrency_total_ht 	= $multicurrency_total_ht;
1958
        $line->multicurrency_total_tva 	= $multicurrency_total_tva;
1959
        $line->multicurrency_total_ttc 	= $multicurrency_total_ttc;
1960
1961
	    $res = $line->update($notrigger);
1962
1963
	    if ($res < 1) {
1964
		    $this->errors[] = $line->error;
1965
	    } else {
1966
		    // Update total price into invoice record
1967
		    $res = $this->update_price('', 'auto');
1968
	    }
1969
1970
	    return $res;
1971
    }
1972
1973
    /**
1974
     * 	Delete a detail line from database
1975
     *
1976
     * 	@param  int		$rowid      	Id of line to delete
1977
     *	@param	int		$notrigger		1=Does not execute triggers, 0= execute triggers
1978
     * 	@return	int						<0 if KO, >0 if OK
1979
     */
1980
    public function deleteline($rowid, $notrigger = 0)
1981
    {
1982
        if (!$rowid) {
1983
	        $rowid = $this->id;
1984
        }
1985
1986
		$this->db->begin();
1987
1988
		// Libere remise liee a ligne de facture
1989
		$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'societe_remise_except';
1990
		$sql .= ' SET fk_invoice_supplier_line = NULL';
1991
		$sql .= ' WHERE fk_invoice_supplier_line = ' . $rowid;
1992
1993
		dol_syslog(get_class($this) . "::deleteline", LOG_DEBUG);
1994
		$result = $this->db->query($sql);
1995
		if (! $result)
1996
		{
1997
			$this->error = $this->db->error();
1998
			$this->db->rollback();
1999
			return - 2;
2000
		}
2001
2002
	    $line = new SupplierInvoiceLine($this->db);
2003
2004
	    if ($line->fetch($rowid) < 1) {
2005
		    return -1;
2006
	    }
2007
2008
	    $res = $line->delete($notrigger);
2009
2010
	    if ($res < 1) {
2011
			$this->errors[] = $line->error;
2012
			$this->db->rollback();
2013
			return - 3;
2014
	    } else {
2015
			$res = $this->update_price();
2016
2017
			if ($res > 0)
2018
			{
2019
				$this->db->commit();
2020
				return 1;
2021
			}
2022
			else
2023
			{
2024
				$this->db->rollback();
2025
				$this->error = $this->db->lasterror();
2026
				return - 4;
2027
			}
2028
	    }
2029
    }
2030
2031
2032
    /**
2033
     *	Charge les informations d'ordre info dans l'objet facture
2034
     *
2035
     *	@param  int		$id       	Id de la facture a charger
2036
     *	@return	void
2037
     */
2038
    public function info($id)
2039
    {
2040
        $sql = 'SELECT c.rowid, datec, tms as datem, ';
2041
        $sql.= ' fk_user_author, fk_user_modif, fk_user_valid';
2042
        $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_fourn as c';
2043
        $sql.= ' WHERE c.rowid = '.$id;
2044
2045
        $result=$this->db->query($sql);
2046
        if ($result)
2047
        {
2048
            if ($this->db->num_rows($result))
2049
            {
2050
                $obj = $this->db->fetch_object($result);
2051
                $this->id = $obj->rowid;
2052
                if ($obj->fk_user_author)
2053
                {
2054
                    $cuser = new User($this->db);
2055
                    $cuser->fetch($obj->fk_user_author);
2056
                    $this->user_creation     = $cuser;
2057
                }
2058
                if ($obj->fk_user_valid)
2059
                {
2060
                    $vuser = new User($this->db);
2061
                    $vuser->fetch($obj->fk_user_valid);
2062
                    $this->user_validation = $vuser;
2063
                }
2064
                if ($obj->fk_user_modif)
2065
                {
2066
                    $muser = new User($this->db);
2067
                    $muser->fetch($obj->fk_user_modif);
2068
                    $this->user_modification = $muser;
2069
                }
2070
                $this->date_creation     = $this->db->idate($obj->datec);
2071
                $this->date_modification = $this->db->idate($obj->datem);
2072
                //$this->date_validation   = $obj->datev; // This field is not available. Should be store into log table and using this function should be replaced with showing content of log (like for supplier orders)
2073
            }
2074
            $this->db->free($result);
2075
        }
2076
        else
2077
        {
2078
            dol_print_error($this->db);
2079
        }
2080
    }
2081
2082
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2083
    /**
2084
	 *	Renvoi liste des factures remplacables
2085
	 *	Statut validee ou abandonnee pour raison autre + non payee + aucun paiement + pas deja remplacee
2086
	 *
2087
	 *	@param      int		$socid		Id societe
2088
	 *	@return    	array|int			Tableau des factures ('id'=>id, 'ref'=>ref, 'status'=>status, 'paymentornot'=>0/1)
2089
     *                                  <0 if error
2090
     */
2091
    public function list_replacable_supplier_invoices($socid = 0)
2092
	{
2093
        // phpcs:enable
2094
		global $conf;
2095
2096
		$return = array();
2097
2098
		$sql = "SELECT f.rowid as rowid, f.ref, f.fk_statut,";
2099
		$sql.= " ff.rowid as rowidnext";
2100
		$sql.= " FROM ".MAIN_DB_PREFIX."facture_fourn as f";
2101
		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf ON f.rowid = pf.fk_facturefourn";
2102
		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture_fourn as ff ON f.rowid = ff.fk_facture_source";
2103
		$sql.= " WHERE (f.fk_statut = ".self::STATUS_VALIDATED." OR (f.fk_statut = ".self::STATUS_ABANDONED." AND f.close_code = '".self::CLOSECODE_ABANDONED."'))";
2104
		$sql.= " AND f.entity = ".$conf->entity;
2105
		$sql.= " AND f.paye = 0";					// Pas classee payee completement
2106
		$sql.= " AND pf.fk_paiementfourn IS NULL";	// Aucun paiement deja fait
2107
		$sql.= " AND ff.fk_statut IS NULL";			// Renvoi vrai si pas facture de remplacement
2108
		if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid;
2109
		$sql.= " ORDER BY f.ref";
2110
2111
		dol_syslog(get_class($this)."::list_replacable_supplier_invoices", LOG_DEBUG);
2112
		$resql=$this->db->query($sql);
2113
		if ($resql)
2114
		{
2115
			while ($obj=$this->db->fetch_object($resql))
2116
			{
2117
				$return[$obj->rowid]=array(
2118
                    'id' => $obj->rowid,
2119
				    'ref' => $obj->ref,
2120
				    'status' => $obj->fk_statut
2121
                );
2122
			}
2123
			//print_r($return);
2124
			return $return;
2125
		}
2126
		else
2127
		{
2128
			$this->error=$this->db->error();
2129
			return -1;
2130
		}
2131
	}
2132
2133
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2134
	/**
2135
	 *	Renvoi liste des factures qualifiables pour correction par avoir
2136
	 *	Les factures qui respectent les regles suivantes sont retournees:
2137
	 *	(validee + paiement en cours) ou classee (payee completement ou payee partiellement) + pas deja remplacee + pas deja avoir
2138
	 *
2139
	 *	@param		int		$socid		Id societe
2140
	 *	@return    	array|int			Tableau des factures ($id => array('ref'=>,'paymentornot'=>,'status'=>,'paye'=>)
2141
     *                                  <0 if error
2142
	 */
2143
    public function list_qualified_avoir_supplier_invoices($socid = 0)
2144
	{
2145
        // phpcs:enable
2146
		global $conf;
2147
2148
		$return = array();
2149
2150
		$sql = "SELECT f.rowid as rowid, f.ref, f.fk_statut, f.type, f.paye, pf.fk_paiementfourn";
2151
		$sql.= " FROM ".MAIN_DB_PREFIX."facture_fourn as f";
2152
		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf ON f.rowid = pf.fk_facturefourn";
2153
		$sql.= " WHERE f.entity = ".$conf->entity;
2154
		$sql.= " AND f.fk_statut in (".self::STATUS_VALIDATED.",".self::STATUS_CLOSED.")";
2155
        $sql.= " AND NOT EXISTS (SELECT rowid from ".MAIN_DB_PREFIX."facture_fourn as ff WHERE f.rowid = ff.fk_facture_source";
2156
        $sql.= " AND ff.type=".self::TYPE_REPLACEMENT.")";
2157
		$sql.= " AND f.type != ".self::TYPE_CREDIT_NOTE;				// Type non 2 si facture non avoir
2158
		if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid;
2159
		$sql.= " ORDER BY f.ref";
2160
2161
		dol_syslog(get_class($this)."::list_qualified_avoir_supplier_invoices", LOG_DEBUG);
2162
		$resql=$this->db->query($sql);
2163
		if ($resql)
2164
		{
2165
			while ($obj=$this->db->fetch_object($resql))
2166
			{
2167
				$qualified=0;
2168
				if ($obj->fk_statut == self::STATUS_VALIDATED) $qualified=1;
2169
				if ($obj->fk_statut == self::STATUS_CLOSED) $qualified=1;
2170
				if ($qualified)
2171
				{
2172
					$paymentornot=($obj->fk_paiementfourn?1:0);
2173
					$return[$obj->rowid]=array('ref'=>$obj->ref,'status'=>$obj->fk_statut,'type'=>$obj->type,'paye'=>$obj->paye,'paymentornot'=>$paymentornot);
2174
				}
2175
			}
2176
2177
			return $return;
2178
		}
2179
		else
2180
		{
2181
			$this->error=$this->db->error();
2182
			return -1;
2183
		}
2184
	}
2185
2186
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2187
    /**
2188
     *	Load indicators for dashboard (this->nbtodo and this->nbtodolate)
2189
     *
2190
     *	@param      User	$user       Object user
2191
     *	@return WorkboardResponse|int <0 if KO, WorkboardResponse if OK
2192
     */
2193
    public function load_board($user)
2194
    {
2195
        // phpcs:enable
2196
        global $conf, $langs;
2197
2198
        $sql = 'SELECT ff.rowid, ff.date_lim_reglement as datefin, ff.fk_statut';
2199
        $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_fourn as ff';
2200
        if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
1 ignored issue
show
Deprecated Code introduced by
The property User::$societe_id has been deprecated. ( Ignorable by Annotation )

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

2200
        if (!$user->rights->societe->client->voir && !/** @scrutinizer ignore-deprecated */ $user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
Loading history...
2201
        $sql.= ' WHERE ff.paye=0';
2202
        $sql.= ' AND ff.fk_statut > 0';
2203
        $sql.= " AND ff.entity = ".$conf->entity;
2204
        if ($user->societe_id) $sql.=' AND ff.fk_soc = '.$user->societe_id;
1 ignored issue
show
Deprecated Code introduced by
The property User::$societe_id has been deprecated. ( Ignorable by Annotation )

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

2204
        if (/** @scrutinizer ignore-deprecated */ $user->societe_id) $sql.=' AND ff.fk_soc = '.$user->societe_id;
Loading history...
2205
        if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND ff.fk_soc = sc.fk_soc AND sc.fk_user = ".$user->id;
1 ignored issue
show
Deprecated Code introduced by
The property User::$societe_id has been deprecated. ( Ignorable by Annotation )

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

2205
        if (!$user->rights->societe->client->voir && !/** @scrutinizer ignore-deprecated */ $user->societe_id) $sql.= " AND ff.fk_soc = sc.fk_soc AND sc.fk_user = ".$user->id;
Loading history...
2206
2207
        $resql=$this->db->query($sql);
2208
        if ($resql)
2209
        {
2210
	        $langs->load("bills");
2211
	        $now=dol_now();
2212
2213
	        $response = new WorkboardResponse();
2214
	        $response->warning_delay=$conf->facture->fournisseur->warning_delay/60/60/24;
2215
	        $response->label=$langs->trans("SupplierBillsToPay");
2216
2217
	        $response->url=DOL_URL_ROOT.'/fourn/facture/list.php?search_status=1&mainmenu=billing&leftmenu=suppliers_bills';
2218
	        $response->img=img_object($langs->trans("Bills"), "bill");
2219
2220
            $facturestatic = new FactureFournisseur($this->db);
2221
2222
            while ($obj=$this->db->fetch_object($resql))
2223
            {
2224
                $response->nbtodo++;
2225
2226
                $facturestatic->date_echeance = $this->db->jdate($obj->datefin);
2227
                $facturestatic->statut = $obj->fk_statut;
2228
2229
                if ($facturestatic->hasDelay()) {
2230
	                $response->nbtodolate++;
2231
                }
2232
            }
2233
            $this->db->free($resql);
2234
            return $response;
2235
        }
2236
        else
2237
        {
2238
            dol_print_error($this->db);
2239
            $this->error=$this->db->error();
2240
            return -1;
2241
        }
2242
    }
2243
2244
2245
    /**
2246
     *	Return clicable name (with picto eventually)
2247
     *
2248
     *	@param		int		$withpicto					0=No picto, 1=Include picto into link, 2=Only picto
2249
     *	@param		string	$option						Where point the link
2250
     *	@param		int		$max						Max length of shown ref
2251
     *	@param		int		$short						1=Return just URL
2252
     *	@param		string	$moretitle					Add more text to title tooltip
2253
     *  @param	    int   	$notooltip					1=Disable tooltip
2254
     *  @param      int     $save_lastsearch_value		-1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
2255
     * 	@return		string								String with URL
2256
     */
2257
    public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $moretitle = '', $notooltip = 0, $save_lastsearch_value = -1)
2258
    {
2259
        global $langs, $conf;
2260
2261
        $result='';
2262
2263
        if ($option == 'document')	$url = DOL_URL_ROOT.'/fourn/facture/document.php?facid='.$this->id;
2264
        else $url = DOL_URL_ROOT.'/fourn/facture/card.php?facid='.$this->id;
2265
2266
        if ($short) return $url;
2267
2268
        if ($option !== 'nolink')
2269
        {
2270
        	// Add param to save lastsearch_values or not
2271
        	$add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0);
2272
        	if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1;
2273
        	if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1';
2274
        }
2275
2276
        $picto=$this->picto;
2277
        if ($this->type == self::TYPE_REPLACEMENT) $picto.='r'; // Replacement invoice
2278
        if ($this->type == self::TYPE_CREDIT_NOTE) $picto.='a'; // Credit note
2279
        if ($this->type == self::TYPE_DEPOSIT)     $picto.='d'; // Deposit invoice
2280
2281
        $label = '<u>' . $langs->trans("ShowSupplierInvoice") . '</u>';
2282
        if (! empty($this->ref))
2283
            $label .= '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
2284
        if (! empty($this->ref_supplier))
2285
            $label.= '<br><b>' . $langs->trans('RefSupplier') . ':</b> ' . $this->ref_supplier;
2286
        if (! empty($this->label))
2287
        	$label.= '<br><b>' . $langs->trans('Label') . ':</b> ' . $this->label;
2288
        if (! empty($this->date))
2289
        	$label .= '<br><b>' . $langs->trans('Date') . ':</b> ' . dol_print_date($this->date, 'day');
2290
        if (! empty($this->total_ht))
2291
            $label.= '<br><b>' . $langs->trans('AmountHT') . ':</b> ' . price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
2292
        if (! empty($this->total_tva))
2293
            $label.= '<br><b>' . $langs->trans('VAT') . ':</b> ' . price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
2294
        if (! empty($this->total_ttc))
2295
            $label.= '<br><b>' . $langs->trans('AmountTTC') . ':</b> ' . price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
2296
        if ($this->type == self::TYPE_REPLACEMENT) $label=$langs->transnoentitiesnoconv("ShowInvoiceReplace").': '.$this->ref;
2297
        elseif ($this->type == self::TYPE_CREDIT_NOTE) $label=$langs->transnoentitiesnoconv("ShowInvoiceAvoir").': '.$this->ref;
2298
        elseif ($this->type == self::TYPE_DEPOSIT)     $label=$langs->transnoentitiesnoconv("ShowInvoiceDeposit").': '.$this->ref;
2299
        if ($moretitle) $label.=' - '.$moretitle;
2300
2301
        $ref=$this->ref;
2302
        if (empty($ref)) $ref=$this->id;
2303
2304
        $linkclose='';
2305
        if (empty($notooltip))
2306
        {
2307
            if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
2308
            {
2309
                $label=$langs->trans("ShowSupplierInvoice");
2310
                $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"';
2311
            }
2312
            $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"';
2313
            $linkclose.=' class="classfortooltip"';
2314
        }
2315
2316
        $linkstart = '<a href="'.$url.'"';
2317
        $linkstart.=$linkclose.'>';
2318
        $linkend='</a>';
2319
2320
        $result .= $linkstart;
2321
        if ($withpicto) $result.=img_object(($notooltip?'':$label), $picto, ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1);
2322
        if ($withpicto != 2) $result.= ($max?dol_trunc($ref, $max):$ref);
2323
        $result .= $linkend;
2324
2325
        return $result;
2326
    }
2327
2328
	 /**
2329
      *      Return next reference of supplier invoice not already used (or last reference)
2330
      *      according to numbering module defined into constant INVOICE_SUPPLIER_ADDON_NUMBER
2331
      *
2332
      *      @param	   Societe		$soc		Thirdparty object
2333
      *      @param    string		$mode		'next' for next value or 'last' for last value
2334
      *      @return   string					free ref or last ref
2335
      */
2336
    public function getNextNumRef($soc, $mode = 'next')
2337
    {
2338
        global $db, $langs, $conf;
2339
        $langs->load("orders");
2340
2341
        // Clean parameters (if not defined or using deprecated value)
2342
        if (empty($conf->global->INVOICE_SUPPLIER_ADDON_NUMBER)) $conf->global->INVOICE_SUPPLIER_ADDON_NUMBER='mod_facture_fournisseur_cactus';
2343
2344
        $mybool=false;
2345
2346
        $file = $conf->global->INVOICE_SUPPLIER_ADDON_NUMBER.".php";
2347
        $classname = $conf->global->INVOICE_SUPPLIER_ADDON_NUMBER;
2348
2349
        // Include file with class
2350
        $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
2351
2352
        foreach ($dirmodels as $reldir) {
2353
2354
            $dir = dol_buildpath($reldir."core/modules/supplier_invoice/");
2355
2356
            // Load file with numbering class (if found)
2357
            $mybool|=@include_once $dir.$file;
2358
        }
2359
2360
        if ($mybool === false) {
2361
        	dol_print_error('', "Failed to include file ".$file);
2362
        	return '';
2363
        }
2364
2365
        $obj = new $classname();
2366
        $numref = "";
2367
        $numref = $obj->getNumRef($soc, $this, $mode);
2368
2369
        if ($numref != "")
2370
        {
2371
        	return $numref;
2372
        }
2373
        else
2374
       {
2375
       		$this->error=$obj->error;
2376
        	//dol_print_error($db,get_class($this)."::getNextNumRef ".$obj->error);
2377
        	return false;
2378
        }
2379
    }
2380
2381
2382
    /**
2383
     *  Initialise an instance with random values.
2384
     *  Used to build previews or test instances.
2385
     *	id must be 0 if object instance is a specimen.
2386
     *
2387
	 *	@param	string		$option		''=Create a specimen invoice with lines, 'nolines'=No lines
2388
     *  @return	void
2389
     */
2390
    public function initAsSpecimen($option = '')
2391
    {
2392
        global $langs,$conf;
2393
		include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
2394
2395
        $now = dol_now();
2396
2397
        // Load array of products prodids
2398
        $num_prods = 0;
2399
        $prodids = array();
2400
2401
        $sql = "SELECT rowid";
2402
        $sql.= " FROM ".MAIN_DB_PREFIX."product";
2403
        $sql.= " WHERE entity IN (".getEntity('product').")";
2404
2405
        $resql = $this->db->query($sql);
2406
        if ($resql)
2407
        {
2408
            $num_prods = $this->db->num_rows($resql);
2409
            $i = 0;
2410
            while ($i < $num_prods)
2411
            {
2412
                $i++;
2413
                $row = $this->db->fetch_row($resql);
2414
                $prodids[$i] = $row[0];
2415
            }
2416
        }
2417
2418
        // Initialise parametres
2419
        $this->id=0;
2420
        $this->ref = 'SPECIMEN';
2421
        $this->ref_supplier = 'SUPPLIER_REF_SPECIMEN';
2422
        $this->specimen=1;
2423
        $this->socid = 1;
2424
        $this->date = $now;
2425
        $this->date_lim_reglement=$this->date+3600*24*30;
2426
        $this->cond_reglement_code = 'RECEP';
2427
        $this->mode_reglement_code = 'CHQ';
2428
        $this->note_public='This is a comment (public)';
2429
        $this->note_private='This is a comment (private)';
2430
2431
		if (empty($option) || $option != 'nolines')
2432
		{
2433
	        // Lines
2434
	        $nbp = 5;
2435
	        $xnbp = 0;
2436
	        while ($xnbp < $nbp)
2437
	        {
2438
	            $line=new FactureLigne($this->db);
2439
	            $line->desc=$langs->trans("Description")." ".$xnbp;
2440
	            $line->qty=1;
2441
	            $line->subprice=100;
2442
	            $line->pu_ht=100;		// the canelle template use pu_ht and not subprice
0 ignored issues
show
Bug introduced by
The property pu_ht does not seem to exist on FactureLigne.
Loading history...
2443
	            $line->price=100;
0 ignored issues
show
Bug introduced by
The property price does not exist on FactureLigne. Did you mean price_level?
Loading history...
2444
	            $line->tva_tx=19.6;
2445
	            $line->localtax1_tx=0;
2446
	            $line->localtax2_tx=0;
2447
				if ($xnbp == 2)
2448
				{
2449
				    $line->total_ht=50;
2450
				    $line->total_ttc=59.8;
2451
				    $line->total_tva=9.8;
2452
	    			$line->remise_percent=50;
2453
				}
2454
				else
2455
				{
2456
				    $line->total_ht=100;
2457
				    $line->total_ttc=119.6;
2458
				    $line->total_tva=19.6;
2459
	    			$line->remise_percent=0;
2460
				}
2461
2462
	            if ($num_prods > 0)
2463
	            {
2464
					$prodid = mt_rand(1, $num_prods);
2465
	            	$line->fk_product=$prodids[$prodid];
2466
	            }
2467
	            $line->product_type=0;
2468
2469
	            $this->lines[$xnbp]=$line;
2470
2471
	    		$this->total_ht       += $line->total_ht;
2472
	    		$this->total_tva      += $line->total_tva;
2473
	    		$this->total_ttc      += $line->total_ttc;
2474
2475
	    		$xnbp++;
2476
	        }
2477
		}
2478
2479
        $this->amount_ht      = $xnbp*100;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $xnbp does not seem to be defined for all execution paths leading up to this point.
Loading history...
2480
        $this->total_ht       = $xnbp*100;
2481
        $this->total_tva      = $xnbp*19.6;
2482
        $this->total_ttc      = $xnbp*119.6;
2483
    }
2484
2485
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2486
	/**
2487
	 *      Load indicators for dashboard (this->nbtodo and this->nbtodolate)
2488
	 *
2489
	 *      @return         int     <0 if KO, >0 if OK
2490
     */
2491
    public function load_state_board()
2492
	{
2493
        // phpcs:enable
2494
		global $conf, $user;
2495
2496
		$this->nb=array();
2497
2498
		$clause = "WHERE";
2499
2500
		$sql = "SELECT count(f.rowid) as nb";
2501
		$sql.= " FROM ".MAIN_DB_PREFIX."facture_fourn as f";
2502
		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid";
2503
		if (!$user->rights->societe->client->voir && !$user->societe_id)
2504
		{
2505
			$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc";
2506
			$sql.= " WHERE sc.fk_user = " .$user->id;
2507
			$clause = "AND";
2508
		}
2509
		$sql.= " ".$clause." f.entity = ".$conf->entity;
2510
2511
		$resql=$this->db->query($sql);
2512
		if ($resql)
2513
		{
2514
			while ($obj=$this->db->fetch_object($resql))
2515
			{
2516
				$this->nb["supplier_invoices"]=$obj->nb;
2517
			}
2518
            $this->db->free($resql);
2519
			return 1;
2520
		}
2521
		else
2522
		{
2523
			dol_print_error($this->db);
2524
			$this->error=$this->db->error();
2525
			return -1;
2526
		}
2527
	}
2528
2529
    /**
2530
     *	Load an object from its id and create a new one in database
2531
     *
2532
     *	@param      User	$user        	User that clone
2533
     *	@param      int		$fromid     	Id of object to clone
2534
     *	@param		int		$invertdetail	Reverse sign of amounts for lines
2535
     * 	@return		int						New id of clone
2536
     */
2537
    public function createFromClone(User $user, $fromid, $invertdetail = 0)
2538
    {
2539
        global $langs;
2540
2541
        $error=0;
2542
2543
        $object=new FactureFournisseur($this->db);
2544
2545
		$this->db->begin();
2546
2547
        // Load source object
2548
        $object->fetch($fromid);
2549
        $object->id=0;
2550
        $object->statut=self::STATUS_DRAFT;
2551
2552
        // Clear fields
2553
        $object->ref_supplier       = (empty($this->ref_supplier) ? $langs->trans("CopyOf").' '.$object->ref_supplier : $this->ref_supplier);
2554
        $object->author             = $user->id;
2555
        $object->user_valid         = '';
2556
        $object->fk_facture_source  = 0;
2557
        $object->date_creation      = '';
2558
        $object->date_validation    = '';
2559
        $object->date               = (empty($this->date) ? '' : $this->date);
1 ignored issue
show
Documentation Bug introduced by
It seems like empty($this->date) ? '' : $this->date 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...
2560
        $object->date_echeance      = '';
1 ignored issue
show
Documentation Bug introduced by
The property $date_echeance was declared of type integer, but '' is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
2561
        $object->ref_client         = '';
2562
        $object->close_code         = '';
2563
        $object->close_note         = '';
2564
2565
        // Loop on each line of new invoice
2566
        foreach($object->lines as $i => $line)
2567
        {
2568
            if (isset($object->lines[$i]->info_bits) && ($object->lines[$i]->info_bits & 0x02) == 0x02)	// We do not clone line of discounts
2569
            {
2570
                unset($object->lines[$i]);
2571
            }
2572
        }
2573
2574
        // Create clone
2575
        $object->context['createfromclone'] = 'createfromclone';
2576
        $result=$object->create($user);
2577
2578
        // Other options
2579
        if ($result < 0)
2580
        {
2581
            $this->error=$object->error;
2582
            $error++;
2583
        }
2584
2585
        if (! $error)
2586
        {
2587
2588
        }
2589
2590
        unset($object->context['createfromclone']);
2591
2592
        // End
2593
        if (! $error)
2594
        {
2595
            $this->db->commit();
2596
            return $object->id;
2597
        }
2598
        else
2599
        {
2600
            $this->db->rollback();
2601
            return -1;
2602
        }
2603
    }
2604
2605
	/**
2606
	 *	Create a document onto disk according to template model.
2607
	 *
2608
	 *	@param	    string		$modele			Force template to use ('' to not force)
2609
	 *	@param		Translate	$outputlangs	Object lang a utiliser pour traduction
2610
	 *  @param      int			$hidedetails    Hide details of lines
2611
	 *  @param      int			$hidedesc       Hide description
2612
	 *  @param      int			$hideref        Hide ref
2613
         *  @param   null|array  $moreparams     Array to provide more information
2614
	 *  @return     int         				<0 if KO, 0 if nothing done, >0 if OK
2615
	 */
2616
	public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
2617
	{
2618
		global $conf, $user, $langs;
2619
2620
		$langs->load("suppliers");
2621
2622
		// Set the model on the model name to use
2623
		if (empty($modele))
2624
		{
2625
			if (! empty($conf->global->INVOICE_SUPPLIER_ADDON_PDF))
2626
			{
2627
				$modele = $conf->global->INVOICE_SUPPLIER_ADDON_PDF;
2628
			}
2629
			else
2630
			{
2631
				$modele = '';       // No default value. For supplier invoice, we allow to disable all PDF generation
2632
			}
2633
		}
2634
2635
		if (empty($modele))
2636
		{
2637
		    return 0;
2638
		}
2639
		else
2640
		{
2641
            $modelpath = "core/modules/supplier_invoice/pdf/";
2642
2643
            return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2644
		}
2645
	}
2646
2647
	/**
2648
	 * Returns the rights used for this class
2649
	 * @return stdClass
2650
	 */
2651
	public function getRights()
2652
	{
2653
		global $user;
2654
2655
		return $user->rights->fournisseur->facture;
2656
	}
2657
2658
	/**
2659
	 * Function used to replace a thirdparty id with another one.
2660
	 *
2661
	 * @param DoliDB $db Database handler
2662
	 * @param int $origin_id Old thirdparty id
2663
	 * @param int $dest_id New thirdparty id
2664
	 * @return bool
2665
	 */
2666
	public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
2667
	{
2668
		$tables = array(
2669
			'facture_fourn'
2670
		);
2671
2672
		return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
2673
	}
2674
2675
    /**
2676
     * Is the payment of the supplier invoice having a delay?
2677
     *
2678
     * @return bool
2679
     */
2680
    public function hasDelay()
2681
    {
2682
        global $conf;
2683
2684
        $now = dol_now();
2685
2686
        if (!$this->date_echeance) {
2687
            return false;
2688
        }
2689
2690
        return ($this->statut == self::STATUS_VALIDATED) && ($this->date_echeance < ($now - $conf->facture->fournisseur->warning_delay));
2691
    }
2692
}
2693
2694
2695
2696
/**
2697
 *  Class to manage line invoices
2698
 */
2699
class SupplierInvoiceLine extends CommonObjectLine
2700
{
2701
	/**
2702
	 * @var string ID to identify managed object
2703
	 */
2704
	public $element='facture_fourn_det';
2705
2706
	/**
2707
	 * @var string Name of table without prefix where object is stored
2708
	 */
2709
	public $table_element='facture_fourn_det';
2710
2711
	public $oldline;
2712
2713
	/**
2714
	 * @deprecated
2715
	 * @see $product_ref
2716
	 */
2717
	public $ref;
2718
2719
	/**
2720
	 * Internal ref
2721
	 * @var string
2722
	 */
2723
	public $product_ref;
2724
2725
	/**
2726
	 * Supplier reference of price when we added the line. May have been changed after line was added.
2727
	 * TODO Rename field ref to ref_supplier into table llx_facture_fourn_det and llx_commande_fournisseurdet and update fields into updateline
2728
	 * @var string
2729
	 */
2730
	public $ref_supplier;
2731
2732
	/**
2733
	 * Product description
2734
	 * @var string
2735
	 */
2736
	public $product_desc;
2737
2738
	/**
2739
	 * Unit price before taxes
2740
	 * @var float
2741
	 * @deprecated Use $subprice
2742
	 * @see $subprice
2743
	 */
2744
	public $pu_ht;
2745
2746
	/**
2747
	 * Unit price excluded taxes
2748
	 * @var float
2749
	 */
2750
	public $subprice;
2751
2752
	/**
2753
	 * Unit price included taxes
2754
	 * @var float
2755
	 */
2756
	public $pu_ttc;
2757
2758
2759
	/**
2760
	 * Id of the corresponding supplier invoice
2761
	 * @var int
2762
	 */
2763
	public $fk_facture_fourn;
2764
2765
	/**
2766
	 * Product label
2767
	 * This field may contains label of product (when invoice create from order)
2768
	 * @var string
2769
	 */
2770
	public $label;
2771
2772
	/**
2773
	 * Description of the line
2774
	 * @var string
2775
	 */
2776
	public $description;
2777
2778
	public $date_start;
2779
	public $date_end;
2780
2781
	public $skip_update_total; // Skip update price total for special lines
2782
2783
	/**
2784
	 * @var int Situation advance percentage
2785
	 */
2786
	public $situation_percent;
2787
2788
	/**
2789
	 * @var int Previous situation line id reference
2790
	 */
2791
	public $fk_prev_id;
2792
2793
	public $tva_tx;
2794
	public $localtax1_tx;
2795
	public $localtax2_tx;
2796
	public $qty;
2797
	public $remise_percent;
2798
	public $total_ht;
2799
	public $total_ttc;
2800
	public $total_tva;
2801
	public $total_localtax1;
2802
	public $total_localtax2;
2803
2804
	/**
2805
     * @var int ID
2806
     */
2807
	public $fk_product;
2808
2809
	public $product_type;
2810
	public $product_label;
2811
	public $info_bits;
2812
2813
	/**
2814
     * @var int ID
2815
     */
2816
	public $fk_parent_line;
2817
2818
	public $special_code;
2819
	public $rang;
2820
	public $localtax1_type;
2821
	public $localtax2_type;
2822
2823
	// Multicurrency
2824
	/**
2825
     * @var int ID
2826
     */
2827
	public $fk_multicurrency;
2828
2829
	public $multicurrency_code;
2830
	public $multicurrency_subprice;
2831
	public $multicurrency_total_ht;
2832
	public $multicurrency_total_tva;
2833
	public $multicurrency_total_ttc;
2834
2835
	/**
2836
     *	Constructor
2837
     *
2838
     *  @param		DoliDB		$db      Database handler
2839
     */
2840
    public function __construct($db)
2841
    {
2842
        $this->db= $db;
2843
    }
2844
2845
	/**
2846
	 * Retrieves a supplier invoice line
2847
	 *
2848
	 * @param    int    $rowid    Line id
2849
	 * @return   int              <0 KO; 0 NOT FOUND; 1 OK
2850
	 */
2851
	public function fetch($rowid)
2852
	{
2853
		$sql = 'SELECT f.rowid, f.ref as ref_supplier, f.description, f.date_start, f.date_end, f.pu_ht, f.pu_ttc, f.qty, f.remise_percent, f.tva_tx';
2854
		$sql.= ', f.localtax1_type, f.localtax2_type, f.localtax1_tx, f.localtax2_tx, f.total_localtax1, f.total_localtax2 ';
2855
		$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';
2856
		$sql.= ', p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.description as product_desc';
2857
		$sql.= ', f.multicurrency_subprice, f.multicurrency_total_ht, f.multicurrency_total_tva, multicurrency_total_ttc';
2858
		$sql.= ' FROM '.MAIN_DB_PREFIX.'facture_fourn_det as f';
2859
		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON f.fk_product = p.rowid';
2860
		$sql.= ' WHERE f.rowid = '.$rowid;
2861
		$sql.= ' ORDER BY f.rang, f.rowid';
2862
2863
		$query = $this->db->query($sql);
2864
2865
		if (!$query) {
2866
			$this->errors[] = $this->db->error();
2867
			return -1;
2868
		}
2869
2870
		if (!$this->db->num_rows($query)) {
2871
			return 0;
2872
		}
2873
2874
		$obj = $this->db->fetch_object($query);
2875
2876
		$this->id				= $obj->rowid;
2877
		$this->rowid				= $obj->rowid;
2878
		$this->fk_facture_fourn			= $obj->fk_facture_fourn;
2879
		$this->description		= $obj->description;
2880
		$this->date_start		= $obj->date_start;
2881
		$this->date_end			= $obj->date_end;
2882
		$this->product_ref		= $obj->product_ref;
2883
		$this->ref_supplier		= $obj->ref_supplier;
2884
		$this->libelle			= $obj->label;
2885
		$this->label  			= $obj->label;
2886
		$this->product_desc		= $obj->product_desc;
2887
		$this->subprice			= $obj->pu_ht;
2888
		$this->pu_ht				= $obj->pu_ht;
2889
		$this->pu_ttc			= $obj->pu_ttc;
2890
		$this->tva_tx			= $obj->tva_tx;
2891
		$this->localtax1_tx		= $obj->localtax1_tx;
2892
		$this->localtax2_tx		= $obj->localtax2_tx;
2893
		$this->localtax1_type		= $obj->localtax1_type;
2894
		$this->localtax2_type		= $obj->localtax2_type;
2895
		$this->qty				= $obj->qty;
2896
		$this->remise_percent    = $obj->remise_percent;
2897
		$this->tva				= $obj->total_tva;			// deprecated
2898
		$this->total_ht			= $obj->total_ht;
2899
		$this->total_tva			= $obj->total_tva;
2900
		$this->total_localtax1	= $obj->total_localtax1;
2901
		$this->total_localtax2	= $obj->total_localtax2;
2902
		$this->total_ttc			= $obj->total_ttc;
2903
		$this->fk_product		= $obj->fk_product;
2904
		$this->product_type		= $obj->product_type;
2905
		$this->product_label		= $obj->product_label;
2906
		$this->info_bits		    = $obj->info_bits;
2907
		$this->tva_npr              = ($obj->info_bits & 1 == 1) ? 1 : 0;
2908
		$this->fk_parent_line    = $obj->fk_parent_line;
2909
		$this->special_code		= $obj->special_code;
2910
		$this->rang       		= $obj->rang;
2911
		$this->fk_unit           = $obj->fk_unit;
2912
2913
		$this->multicurrency_subprice = $obj->multicurrency_subprice;
2914
		$this->multicurrency_total_ht = $obj->multicurrency_total_ht;
2915
		$this->multicurrency_total_tva = $obj->multicurrency_total_tva;
2916
		$this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
2917
2918
		$this->fetch_optionals();
2919
2920
		return 1;
2921
	}
2922
2923
	/**
2924
	 * Deletes a line
2925
	 *
2926
	 * @param     bool|int   $notrigger     1=Does not execute triggers, 0= execute triggers
2927
	 * @return    int                       0 if KO, 1 if OK
2928
	 */
2929
	public function delete($notrigger = 0)
2930
	{
2931
		global $user;
2932
2933
		dol_syslog(get_class($this)."::deleteline rowid=".$this->id, LOG_DEBUG);
2934
2935
		$error = 0;
2936
2937
		$this->db->begin();
2938
2939
		if (!$notrigger) {
2940
			if ($this->call_trigger('LINEBILL_SUPPLIER_DELETE', $user) < 0) {
2941
				$error++;
2942
			}
2943
		}
2944
2945
		$this->deleteObjectLinked();
2946
2947
		if (!$error) {
2948
			// Supprime ligne
2949
			$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn_det ';
2950
			$sql .= ' WHERE rowid = '.$this->id;
2951
			dol_syslog(get_class($this)."::delete", LOG_DEBUG);
2952
			$resql = $this->db->query($sql);
2953
			if (!$resql) {
2954
				$error++;
2955
				$this->error = $this->db->lasterror();
2956
			}
2957
		}
2958
2959
		if (! $error)
2960
		{
2961
			$this->db->commit();
2962
			return 1;
2963
		}
2964
		else
2965
		{
2966
			$this->db->rollback();
2967
			return -1;
2968
		}
2969
	}
2970
2971
	/**
2972
	 * Update a supplier invoice line
2973
	 *
2974
	 * @param int $notrigger Disable triggers
2975
	 * @return int <0 if KO, >0 if OK
2976
	 */
2977
	public function update($notrigger = 0)
2978
	{
2979
		global $conf;
2980
2981
		$pu = price2num($this->pu_ht);
1 ignored issue
show
Deprecated Code introduced by
The property SupplierInvoiceLine::$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

2981
		$pu = price2num(/** @scrutinizer ignore-deprecated */ $this->pu_ht);

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...
2982
		$qty  = price2num($this->qty);
2983
2984
		// Check parameters
2985
		if (empty($this->qty)) $this->qty=0;
2986
2987
		if ($this->product_type < 0) {
2988
			return -1;
2989
		}
2990
2991
		// Clean parameters
2992
		if (empty($this->remise_percent)) $this->remise_percent = 0;
2993
		if (empty($this->tva_tx))  		  $this->tva_tx = 0;
2994
		if (empty($this->localtax1_tx))   $this->localtax1_tx = 0;
2995
		if (empty($this->localtax2_tx))   $this->localtax2_tx = 0;
2996
2997
		$this->db->begin();
2998
2999
		if (empty($this->fk_product))
3000
		{
3001
			$fk_product = "null";
3002
		} else {
3003
			$fk_product = $this->fk_product;
3004
		}
3005
3006
		if (empty($this->fk_unit)) {
3007
			$fk_unit = "null";
3008
		} else {
3009
		    $fk_unit = "'".$this->db->escape($this->fk_unit)."'";
3010
		}
3011
3012
		$sql = "UPDATE ".MAIN_DB_PREFIX."facture_fourn_det SET";
3013
		$sql.= "  description ='".$this->db->escape($this->description)."'";
3014
		$sql.= ", ref ='".$this->db->escape($this->ref_supplier ? $this->ref_supplier : $this->ref)."'";
1 ignored issue
show
Deprecated Code introduced by
The property SupplierInvoiceLine::$ref has been deprecated. ( Ignorable by Annotation )

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

3014
		$sql.= ", ref ='".$this->db->escape($this->ref_supplier ? $this->ref_supplier : /** @scrutinizer ignore-deprecated */ $this->ref)."'";
Loading history...
3015
		$sql.= ", date_start = ".($this->date_start != '' ? "'".$this->db->idate($this->date_start)."'" : "null");
3016
		$sql.= ", date_end = ".($this->date_end != '' ? "'".$this->db->idate($this->date_end)."'" : "null");
3017
		$sql.= ", pu_ht = ".price2num($this->pu_ht);
1 ignored issue
show
Deprecated Code introduced by
The property SupplierInvoiceLine::$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

3017
		$sql.= ", pu_ht = ".price2num(/** @scrutinizer ignore-deprecated */ $this->pu_ht);

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...
3018
		$sql.= ", pu_ttc = ".price2num($this->pu_ttc);
3019
		$sql.= ", qty = ".price2num($this->qty);
3020
		$sql.= ", remise_percent = ".price2num($this->remise_percent);
3021
		$sql.= ", vat_src_code = '".$this->db->escape(empty($this->vat_src_code)?'':$this->vat_src_code)."'";
0 ignored issues
show
Bug Best Practice introduced by
The property vat_src_code does not exist on SupplierInvoiceLine. Did you maybe forget to declare it?
Loading history...
3022
		$sql.= ", tva_tx = ".price2num($this->tva_tx);
3023
		$sql.= ", localtax1_tx = ".price2num($this->localtax1_tx);
3024
		$sql.= ", localtax2_tx = ".price2num($this->localtax2_tx);
3025
		$sql.= ", localtax1_type = '".$this->db->escape($this->localtax1_type)."'";
3026
		$sql.= ", localtax2_type = '".$this->db->escape($this->localtax2_type)."'";
3027
		$sql.= ", total_ht = ".price2num($this->total_ht);
3028
		$sql.= ", tva= ".price2num($this->total_tva);
3029
		$sql.= ", total_localtax1= ".price2num($this->total_localtax1);
3030
		$sql.= ", total_localtax2= ".price2num($this->total_localtax2);
3031
		$sql.= ", total_ttc = ".price2num($this->total_ttc);
3032
		$sql.= ", fk_product = ".$fk_product;
3033
		$sql.= ", product_type = ".$this->product_type;
3034
		$sql.= ", info_bits = ".$this->info_bits;
3035
		$sql.= ", fk_unit = ".$fk_unit;
3036
3037
		// Multicurrency
3038
		$sql.= " , multicurrency_subprice=".price2num($this->multicurrency_subprice)."";
3039
        $sql.= " , multicurrency_total_ht=".price2num($this->multicurrency_total_ht)."";
3040
        $sql.= " , multicurrency_total_tva=".price2num($this->multicurrency_total_tva)."";
3041
        $sql.= " , multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc)."";
3042
3043
		$sql.= " WHERE rowid = ".$this->id;
3044
3045
		dol_syslog(get_class($this)."::update", LOG_DEBUG);
3046
		$resql = $this->db->query($sql);
3047
3048
		if (!$resql) {
3049
			$this->db->rollback();
3050
			$this->error = $this->db->lasterror();
3051
			return -1;
3052
		}
3053
3054
		$this->rowid = $this->id;
3055
		$error = 0;
3056
3057
		if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
3058
		{
3059
			$result = $this->insertExtraFields();
3060
			if ($result < 0)
3061
			{
3062
				$error++;
3063
			}
3064
		}
3065
3066
		if (! $error && ! $notrigger)
3067
		{
3068
			global $langs, $user;
3069
3070
			// Call trigger
3071
			if ($this->call_trigger('LINEBILL_SUPPLIER_UPDATE', $user) < 0) {
3072
				$this->db->rollback();
3073
				return -1;
3074
			}
3075
			// End call triggers
3076
		}
3077
3078
		if ($error) {
3079
			$this->db->rollback();
3080
			return -1;
3081
		}
3082
3083
		$this->db->commit();
3084
		return 1;
3085
	}
3086
3087
    /**
3088
     *	Insert line into database
3089
     *
3090
     *	@param      int		$notrigger		1 no triggers
3091
     *	@return		int						<0 if KO, >0 if OK
3092
     */
3093
    public function insert($notrigger = 0)
3094
    {
3095
        global $user,$conf;
3096
3097
        $error=0;
3098
3099
        dol_syslog(get_class($this)."::insert rang=".$this->rang, LOG_DEBUG);
3100
3101
        // Clean parameters
3102
        $this->desc=trim($this->desc);
3103
        if (empty($this->tva_tx)) $this->tva_tx=0;
3104
        if (empty($this->localtax1_tx)) $this->localtax1_tx=0;
3105
        if (empty($this->localtax2_tx)) $this->localtax2_tx=0;
3106
        if (empty($this->localtax1_type)) $this->localtax1_type='0';
3107
        if (empty($this->localtax2_type)) $this->localtax2_type='0';
3108
        if (empty($this->total_tva)) $this->total_tva=0;
3109
        if (empty($this->total_localtax1)) $this->total_localtax1=0;
3110
        if (empty($this->total_localtax2)) $this->total_localtax2=0;
3111
        if (empty($this->rang)) $this->rang=0;
3112
        if (empty($this->remise_percent)) $this->remise_percent=0;
3113
        if (empty($this->info_bits)) $this->info_bits=0;
3114
        if (empty($this->subprice)) $this->subprice=0;
3115
        if (empty($this->special_code)) $this->special_code=0;
3116
        if (empty($this->fk_parent_line)) $this->fk_parent_line=0;
3117
        if (! isset($this->situation_percent) || $this->situation_percent > 100 || (string) $this->situation_percent == '') $this->situation_percent = 100;
3118
3119
        if (empty($this->pa_ht)) $this->pa_ht=0;
3120
        if (empty($this->multicurrency_subprice)) $this->multicurrency_subprice=0;
3121
        if (empty($this->multicurrency_total_ht)) $this->multicurrency_total_ht=0;
3122
        if (empty($this->multicurrency_total_tva)) $this->multicurrency_total_tva=0;
3123
        if (empty($this->multicurrency_total_ttc)) $this->multicurrency_total_ttc=0;
3124
3125
3126
        // Check parameters
3127
        if ($this->product_type < 0)
3128
        {
3129
            $this->error='ErrorProductTypeMustBe0orMore';
3130
            return -1;
3131
        }
3132
        if (! empty($this->fk_product))
3133
        {
3134
            // Check product exists
3135
            $result=Product::isExistingObject('product', $this->fk_product);
3136
            if ($result <= 0)
3137
            {
3138
                $this->error='ErrorProductIdDoesNotExists';
3139
                return -1;
3140
            }
3141
        }
3142
3143
        $this->db->begin();
3144
3145
        // Insertion dans base de la ligne
3146
        $sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element;
3147
        $sql.= ' (fk_facture_fourn, fk_parent_line, label, description, ref, qty,';
3148
        $sql.= ' vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
3149
        $sql.= ' fk_product, product_type, remise_percent, pu_ht, pu_ttc,';
3150
        $sql.= ' date_start, date_end, fk_code_ventilation, rang, special_code,';
3151
        $sql.= ' info_bits, total_ht, tva, total_ttc, total_localtax1, total_localtax2, fk_unit';
3152
        $sql.= ', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc';
3153
        $sql.= ')';
3154
        $sql.= " VALUES (".$this->fk_facture_fourn.",";
3155
        $sql.= " ".($this->fk_parent_line>0?"'".$this->db->escape($this->fk_parent_line)."'":"null").",";
3156
        $sql.= " ".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null").",";
3157
        $sql.= " '".$this->db->escape($this->desc ? $this->desc : $this->description)."',";
3158
        $sql.= " '".$this->db->escape($this->ref_supplier)."',";
3159
        $sql.= " ".price2num($this->qty).",";
3160
3161
        $sql.= " ".(empty($this->vat_src_code)?"''":"'".$this->db->escape($this->vat_src_code)."'").",";
0 ignored issues
show
Bug Best Practice introduced by
The property vat_src_code does not exist on SupplierInvoiceLine. Did you maybe forget to declare it?
Loading history...
3162
        $sql.= " ".price2num($this->tva_tx).",";
3163
        $sql.= " ".price2num($this->localtax1_tx).",";
3164
        $sql.= " ".price2num($this->localtax2_tx).",";
3165
        $sql.= " '".$this->db->escape($this->localtax1_type)."',";
3166
        $sql.= " '".$this->db->escape($this->localtax2_type)."',";
3167
        $sql.= ' '.(! empty($this->fk_product)?$this->fk_product:"null").',';
3168
        $sql.= " ".$this->product_type.",";
3169
        $sql.= " ".price2num($this->remise_percent).",";
3170
        $sql.= " ".price2num($this->subprice).",";
3171
        $sql.= " ".(! empty($this->qty)?price2num($this->total_ttc / $this->qty):price2num($this->total_ttc)).",";
3172
        $sql.= " ".(! empty($this->date_start)?"'".$this->db->idate($this->date_start)."'":"null").",";
3173
        $sql.= " ".(! empty($this->date_end)?"'".$this->db->idate($this->date_end)."'":"null").",";
3174
        $sql.= ' '.(! empty($this->fk_code_ventilation)?$this->fk_code_ventilation:0).',';
0 ignored issues
show
Bug Best Practice introduced by
The property fk_code_ventilation does not exist on SupplierInvoiceLine. Did you maybe forget to declare it?
Loading history...
3175
        $sql.= ' '.$this->rang.',';
3176
        $sql.= ' '.$this->special_code.',';
3177
        $sql.= " '".$this->db->escape($this->info_bits)."',";
3178
        $sql.= " ".price2num($this->total_ht).",";
3179
        $sql.= " ".price2num($this->total_tva).",";
3180
        $sql.= " ".price2num($this->total_ttc).",";
3181
        $sql.= " ".price2num($this->total_localtax1).",";
3182
        $sql.= " ".price2num($this->total_localtax2);
3183
        $sql .= ", ".(!$this->fk_unit ? 'NULL' : $this->fk_unit);
3184
        $sql.= ", ".(int) $this->fk_multicurrency;
3185
        $sql.= ", '".$this->db->escape($this->multicurrency_code)."'";
3186
        $sql.= ", ".price2num($this->multicurrency_subprice);
3187
        $sql.= ", ".price2num($this->multicurrency_total_ht);
3188
        $sql.= ", ".price2num($this->multicurrency_total_tva);
3189
        $sql.= ", ".price2num($this->multicurrency_total_ttc);
3190
        $sql.= ')';
3191
3192
        $resql=$this->db->query($sql);
3193
        if ($resql)
3194
        {
3195
            $this->id=$this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
3196
            $this->rowid=$this->id;		// backward compatibility
3197
3198
            if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
3199
            {
3200
                $result=$this->insertExtraFields();
3201
                if ($result < 0)
3202
                {
3203
                    $error++;
3204
                }
3205
            }
3206
3207
            if (! $error && ! $notrigger)
3208
            {
3209
                // Call trigger
3210
                $result=$this->call_trigger('LINEBILL_SUPPLIER_CREATE', $user);
3211
                if ($result < 0)
3212
                {
3213
                    $this->db->rollback();
3214
                    return -2;
3215
                }
3216
                // End call triggers
3217
            }
3218
3219
            $this->db->commit();
3220
            return $this->id;
3221
        }
3222
        else
3223
        {
3224
            $this->error=$this->db->error();
3225
            $this->db->rollback();
3226
            return -2;
3227
        }
3228
    }
3229
3230
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3231
    /**
3232
     *  Mise a jour de l'objet ligne de commande en base
3233
     *
3234
     *  @return		int		<0 si ko, >0 si ok
3235
     */
3236
    public function update_total()
3237
    {
3238
        // phpcs:enable
3239
        $this->db->begin();
3240
3241
        // Mise a jour ligne en base
3242
        $sql = "UPDATE ".MAIN_DB_PREFIX."facture_fourn_det SET";
3243
        $sql.= "  total_ht='".price2num($this->total_ht)."'";
3244
        $sql.= ", tva='".price2num($this->total_tva)."'";
3245
        $sql.= ", total_localtax1='".price2num($this->total_localtax1)."'";
3246
        $sql.= ", total_localtax2='".price2num($this->total_localtax2)."'";
3247
        $sql.= ", total_ttc='".price2num($this->total_ttc)."'";
3248
        $sql.= " WHERE rowid = ".$this->rowid;
1 ignored issue
show
Deprecated Code introduced by
The property 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

3248
        $sql.= " WHERE rowid = "./** @scrutinizer ignore-deprecated */ $this->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...
3249
3250
        dol_syslog("FactureFournisseurLigne.class.php::update_total", LOG_DEBUG);
3251
3252
        $resql=$this->db->query($sql);
3253
        if ($resql)
3254
        {
3255
            $this->db->commit();
3256
            return 1;
3257
        }
3258
        else
3259
        {
3260
            $this->error=$this->db->error();
3261
            $this->db->rollback();
3262
            return -2;
3263
        }
3264
    }
3265
}
3266