Passed
Push — EXTRACT_CLASSES ( c25e41...9f3ede )
by Rafael
55:18
created

FactureFournisseurRec::create()   F

Complexity

Conditions 50
Paths > 20000

Size

Total Lines 217
Code Lines 168

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 50
eloc 168
nc 1889534464
nop 3
dl 0
loc 217
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

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

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

294
        /** @scrutinizer ignore-deprecated */ $this->titre = empty($this->titre) ? '' : $this->titre; // deprecated

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Loading history...
636
                $this->title                    = $obj->title;
637
                $this->subtype                        = $obj->subtype;
638
                $this->ref                      = $obj->title;
639
                $this->ref_supplier             = $obj->ref_supplier;
640
                $this->entity                   = $obj->entity;
641
                $this->socid                    = $obj->fk_soc;
642
                $this->date_creation            = $obj->datec;
643
                $this->date_modification        = $obj->tms;
644
                $this->suspended                = $obj->suspended;
645
                $this->libelle                  = $obj->label;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Fourn\Clas...ournisseurRec::$libelle has been deprecated: Use $label ( Ignorable by Annotation )

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1372
                    /** @scrutinizer ignore-deprecated */ $new_fac_fourn->libelle = $facturerec->label;   // deprecated

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

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

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

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1714
        $this->date_lim_reglement = $nownotime + 3600 * 24 * 30;
1715
        $this->cond_reglement_id   = 1;
1716
        $this->cond_reglement_code = 'RECEP';
1717
        $this->date_lim_reglement = $this->calculate_date_lim_reglement();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->calculate_date_lim_reglement() can also be of type string. However, the property $date_lim_reglement is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1718
        $this->mode_reglement_id   = 0; // Not forced to show payment mode CHQ + VIR
1719
        $this->mode_reglement_code = ''; // Not forced to show payment mode CHQ + VIR
1720
        $this->note_public = 'This is a comment (public)';
1721
        $this->note_private = 'This is a comment (private)';
1722
        $this->note = 'This is a comment (private)';
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$note has been deprecated: Use $note_private instead. ( Ignorable by Annotation )

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

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

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

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

Loading history...
1723
        $this->fk_incoterms = 0;
1724
        $this->location_incoterms = '';
1725
1726
        if (empty($option) || $option != 'nolines') {
1727
            // Lines
1728
            $nbp = 5;
1729
            $xnbp = 0;
1730
            while ($xnbp < $nbp) {
1731
                $line = new FactureLigne($this->db);
0 ignored issues
show
Bug introduced by
The type Dolibarr\Code\Fourn\Classes\FactureLigne was not found. Did you mean FactureLigne? If so, make sure to prefix the type with \.
Loading history...
1732
                $line->desc = $langs->trans('Description') . ' ' . $xnbp;
1733
                $line->qty = 1;
1734
                $line->subprice = 100;
1735
                $line->tva_tx = 19.6;
1736
                $line->localtax1_tx = 0;
1737
                $line->localtax2_tx = 0;
1738
                $line->remise_percent = 0;
1739
                if ($xnbp == 1) {        // Qty is negative (product line)
1740
                    $prodid = mt_rand(1, $num_prods);
1741
                    $line->fk_product = $prodids[$prodid];
1742
                    $line->qty = -1;
1743
                    $line->total_ht = -100;
1744
                    $line->total_ttc = -119.6;
1745
                    $line->total_tva = -19.6;
1746
                } elseif ($xnbp == 2) {    // UP is negative (free line)
1747
                    $line->subprice = -100;
1748
                    $line->total_ht = -100;
1749
                    $line->total_ttc = -119.6;
1750
                    $line->total_tva = -19.6;
1751
                    $line->remise_percent = 0;
1752
                } elseif ($xnbp == 3) {    // Discount is 50% (product line)
1753
                    $prodid = mt_rand(1, $num_prods);
1754
                    $line->fk_product = $prodids[$prodid];
1755
                    $line->total_ht = 50;
1756
                    $line->total_ttc = 59.8;
1757
                    $line->total_tva = 9.8;
1758
                    $line->remise_percent = 50;
1759
                } else { // (product line)
1760
                    $prodid = mt_rand(1, $num_prods);
1761
                    $line->fk_product = $prodids[$prodid];
1762
                    $line->total_ht = 100;
1763
                    $line->total_ttc = 119.6;
1764
                    $line->total_tva = 19.6;
1765
                    $line->remise_percent = 0;
1766
                }
1767
1768
                $this->lines[$xnbp] = $line;
1769
                $xnbp++;
1770
1771
                $this->total_ht       += $line->total_ht;
1772
                $this->total_tva      += $line->total_tva;
1773
                $this->total_ttc      += $line->total_ttc;
1774
            }
1775
            $this->revenuestamp = 0;
1776
1777
            // Add a line "offered"
1778
            $line = new FactureLigne($this->db);
1779
            $line->desc = $langs->trans('Description') . ' (offered line)';
1780
            $line->qty = 1;
1781
            $line->subprice = 100;
1782
            $line->tva_tx = 19.6;
1783
            $line->localtax1_tx = 0;
1784
            $line->localtax2_tx = 0;
1785
            $line->remise_percent = 100;
1786
            $line->total_ht = 0;
1787
            $line->total_ttc = 0; // 90 * 1.196
1788
            $line->total_tva = 0;
1789
            $prodid = mt_rand(1, $num_prods);
1790
            $line->fk_product = $prodids[$prodid];
1791
1792
            $this->lines[$xnbp] = $line;
1793
            $xnbp++;
1794
        }
1795
1796
        $this->usenewprice = 0;
1797
1798
        return 1;
1799
    }
1800
1801
    /**
1802
     * Function used to replace a thirdparty id with another one.
1803
     *
1804
     * @param   DoliDB  $dbs        Database handler, because function is static we name it $dbs not $db to avoid breaking coding test
1805
     * @param   int     $origin_id  Old thirdparty id
1806
     * @param   int     $dest_id    New thirdparty id
1807
     * @return  bool
1808
     */
1809
    public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
1810
    {
1811
        $tables = array(
1812
            'facture_fourn_rec'
1813
        );
1814
1815
        return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
1816
    }
1817
1818
    /**
1819
     *  Update frequency and unit
1820
     *
1821
     *  @param      int     $frequency      value of frequency
1822
     *  @param      string  $unit           unit of frequency  (d, m, y)
1823
     *  @return     int                     Return integer <0 if KO, >0 if OK
1824
     */
1825
    public function setFrequencyAndUnit($frequency, $unit)
1826
    {
1827
        if (!$this->table_element) {
1828
            dol_syslog(get_class($this) . '::setFrequencyAndUnit was called on object with property table_element not defined', LOG_ERR);
1829
            return -1;
1830
        }
1831
1832
        if (!empty($frequency) && empty($unit)) {
1833
            dol_syslog(get_class($this) . '::setFrequencyAndUnit was called on object with params frequency defined but unit not defined', LOG_ERR);
1834
            return -2;
1835
        }
1836
1837
        $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
1838
        $sql .= " SET frequency = " . ($frequency ? ((int) $frequency) : "NULL");
1839
        if (!empty($unit)) {
1840
            $sql .= ", unit_frequency = '" . $this->db->escape($unit) . "'";
1841
        }
1842
        $sql .= " WHERE rowid = " . ((int) $this->id);
1843
1844
        dol_syslog(get_class($this) . '::setFrequencyAndUnit', LOG_DEBUG);
1845
1846
        if ($this->db->query($sql)) {
1847
            $this->frequency = $frequency;
1848
            if (!empty($unit)) {
1849
                $this->unit_frequency = $unit;
1850
            }
1851
            return 1;
1852
        } else {
1853
            $this->error = $this->db->lasterror();
1854
            return -1;
1855
        }
1856
    }
1857
1858
    /**
1859
     *  Update the next date of execution
1860
     *
1861
     *  @param      datetime    $date                   date of execution
0 ignored issues
show
Bug introduced by
The type Dolibarr\Code\Fourn\Classes\datetime was not found. Did you mean datetime? If so, make sure to prefix the type with \.
Loading history...
1862
     *  @param      int         $increment_nb_gen_done  0 do nothing more, >0 increment nb_gen_done
1863
     *  @return     int                                 Return integer <0 if KO, >0 if OK
1864
     */
1865
    public function setNextDate($date, $increment_nb_gen_done = 0)
1866
    {
1867
        if (!$this->table_element) {
1868
            dol_syslog(get_class($this) . '::setNextDate was called on object with property table_element not defined', LOG_ERR);
1869
            return -1;
1870
        }
1871
        $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
1872
        $sql .= " SET date_when = " . ($date ? "'" . $this->db->idate($date) . "'" : "NULL");
1873
        if ($increment_nb_gen_done > 0) {
1874
            $sql .= ", nb_gen_done = nb_gen_done + 1";
1875
        }
1876
        $sql .= " WHERE rowid = " . (int) $this->id;
1877
1878
        dol_syslog(get_class($this) . '::setNextDate', LOG_DEBUG);
1879
1880
        if ($this->db->query($sql)) {
1881
            $this->date_when = $date;
1882
            if ($increment_nb_gen_done > 0) {
1883
                $this->nb_gen_done++;
1884
            }
1885
            return 1;
1886
        } else {
1887
            $this->error = $this->db->lasterror();
1888
            return -1;
1889
        }
1890
    }
1891
1892
    /**
1893
     *  Update the maximum period
1894
     *
1895
     *  @param      int     $nb     number of maximum period
1896
     *  @return     int             Return integer <0 if KO, >0 if OK
1897
     */
1898
    public function setMaxPeriod($nb)
1899
    {
1900
        if (!$this->table_element) {
1901
            dol_syslog(get_class($this) . '::setMaxPeriod was called on object with property table_element not defined', LOG_ERR);
1902
            return -1;
1903
        }
1904
1905
        if (empty($nb)) {
1906
            $nb = 0;
1907
        }
1908
1909
        $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
1910
        $sql .= " SET nb_gen_max = " . (int) $nb;
1911
        $sql .= " WHERE rowid = " . (int) $this->id;
1912
1913
        dol_syslog(get_class($this) . '::setMaxPeriod', LOG_DEBUG);
1914
1915
        if ($this->db->query($sql)) {
1916
            $this->nb_gen_max = $nb;
1917
            return 1;
1918
        } else {
1919
            dol_print_error($this->db);
1920
            return -1;
1921
        }
1922
    }
1923
1924
    /**
1925
     *  Update the auto validate flag of invoice
1926
     *
1927
     *  @param      int     $validate       0 to create in draft, 1 to create and validate invoice
1928
     *  @return     int                     Return integer <0 if KO, >0 if OK
1929
     */
1930
    public function setAutoValidate($validate)
1931
    {
1932
        if (!$this->table_element) {
1933
            dol_syslog(get_class($this) . '::setAutoValidate was called on object with property table_element not defined', LOG_ERR);
1934
            return -1;
1935
        }
1936
1937
        $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
1938
        $sql .= " SET auto_validate = " . ((int) $validate);
1939
        $sql .= " WHERE rowid = " . (int) $this->id;
1940
1941
        dol_syslog(get_class($this) . '::setAutoValidate', LOG_DEBUG);
1942
1943
        if ($this->db->query($sql)) {
1944
            $this->auto_validate = $validate;
1945
            return 1;
1946
        } else {
1947
            dol_print_error($this->db);
1948
            return -1;
1949
        }
1950
    }
1951
1952
    /**
1953
     *  Update the auto generate documents
1954
     *
1955
     *  @param      int     $validate       0 no document, 1 to generate document
1956
     *  @return     int                     Return integer <0 if KO, >0 if OK
1957
     */
1958
    public function setGeneratePdf($validate)
1959
    {
1960
        if (!$this->table_element) {
1961
            dol_syslog(get_class($this) . '::setGeneratePdf was called on object with property table_element not defined', LOG_ERR);
1962
            return -1;
1963
        }
1964
1965
        $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
1966
        $sql .= " SET generate_pdf = " . (int) $validate;
1967
        $sql .= " WHERE rowid = " . (int) $this->id;
1968
1969
        dol_syslog(get_class($this) . '::setGeneratePdf', LOG_DEBUG);
1970
1971
        if ($this->db->query($sql)) {
1972
            $this->generate_pdf = $validate;
1973
            return 1;
1974
        } else {
1975
            dol_print_error($this->db);
1976
            return -1;
1977
        }
1978
    }
1979
1980
    /**
1981
     *  Update the model for documents
1982
     *
1983
     *  @param      string      $model      model of document generator
1984
     *  @return     int                     Return integer <0 if KO, >0 if OK
1985
     */
1986
    public function setModelPdf($model)
1987
    {
1988
        if (!$this->table_element) {
1989
            dol_syslog(get_class($this) . '::setModelPdf was called on object with property table_element not defined', LOG_ERR);
1990
            return -1;
1991
        }
1992
1993
        $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
1994
        $sql .= " SET modelpdf = '" . $this->db->escape($model) . "'";
1995
        $sql .= " WHERE rowid = " . (int) $this->id;
1996
1997
        dol_syslog(get_class($this) . '::setModelPdf', LOG_DEBUG);
1998
1999
        if ($this->db->query($sql)) {
2000
            $this->model_pdf = $model;
2001
            return 1;
2002
        } else {
2003
            dol_print_error($this->db);
2004
            return -1;
2005
        }
2006
    }
2007
}
2008