Delivery::valid()   F
last analyzed

Complexity

Conditions 25
Paths 1301

Size

Total Lines 144
Code Lines 92

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 25
eloc 92
nc 1301
nop 2
dl 0
loc 144
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       Rodolphe Quiedeville        <[email protected]>
4
 * Copyright (C) 2005-2014  Regis Houssin               <[email protected]>
5
 * Copyright (C) 2006-2007  Laurent Destailleur         <[email protected]>
6
 * Copyright (C) 2007       Franky Van Liedekerke       <[email protected]>
7
 * Copyright (C) 2011-2023  Philippe Grand	            <[email protected]>
8
 * Copyright (C) 2013       Florian Henry	            <[email protected]>
9
 * Copyright (C) 2014-2015  Marcos García               <[email protected]>
10
 * Copyright (C) 2023-2024  Frédéric France             <[email protected]>
11
 * Copyright (C) 2024		MDW							<[email protected]>
12
 * Copyright (C) 2024       Rafael San José             <[email protected]>
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 3 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
26
 */
27
28
namespace Dolibarr\Code\Delivery\Classes;
29
30
use Dolibarr\Code\Commande\Classes\Commande;
31
use Dolibarr\Code\Core\Classes\Translate;
32
use Dolibarr\Code\Core\Traits\CommonIncoterm;
33
use Dolibarr\Code\Societe\Classes\Societe;
34
use Dolibarr\Code\User\Classes\User;
35
use Dolibarr\Core\Base\CommonObject;
36
use DoliDB;
37
38
/**
39
 *  \file       htdocs/delivery/class/delivery.class.php
40
 *  \ingroup    delivery
41
 *  \brief      Delivery Order Management Class File
42
 */
43
44
45
/**
46
 *  Class to manage receptions
47
 */
48
class Delivery extends CommonObject
49
{
50
    use CommonIncoterm;
0 ignored issues
show
Bug introduced by
The trait Dolibarr\Code\Core\Traits\CommonIncoterm requires the property $code which is not provided by Dolibarr\Code\Delivery\Classes\Delivery.
Loading history...
51
52
    /**
53
     * @var string ID to identify managed object
54
     */
55
    public $element = "delivery";
56
57
    /**
58
     * @var string Field with ID of parent key if this field has a parent
59
     */
60
    public $fk_element = "fk_delivery";
61
62
    /**
63
     * @var string Name of table without prefix where object is stored
64
     */
65
    public $table_element = "delivery";
66
67
    /**
68
     * @var string    Name of subtable line
69
     */
70
    public $table_element_line = "deliverydet";
71
72
    /**
73
     * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
74
     */
75
    public $picto = 'sending';
76
77
    /**
78
     * @var int draft status
79
     */
80
    public $draft;
81
82
    /**
83
     * @var int thirdparty id
84
     */
85
    public $socid;
86
87
    /**
88
     * @var string ref customer
89
     */
90
    public $ref_customer;
91
92
    /**
93
     * @var integer|string Date really received
94
     */
95
    public $date_delivery;
96
97
    /**
98
     * @var integer|string date_creation
99
     */
100
    public $date_creation;
101
102
    /**
103
     * @var integer|string date_valid
104
     */
105
    public $date_valid;
106
107
    /**
108
     * @var string model pdf
109
     */
110
    public $model_pdf;
111
112
    public $commande_id;
113
114
    /**
115
     * @var DeliveryLine[] lines
116
     */
117
    public $lines = array();
118
119
    /**
120
     * @var int user_author_id
121
     */
122
    public $user_author_id;
123
124
125
    /**
126
     * Constructor
127
     *
128
     * @param   DoliDB  $db     Database handler
129
     */
130
    public function __construct($db)
131
    {
132
        $this->db = $db;
133
134
        // List of short language codes for status
135
        $this->labelStatus[-1] = 'StatusDeliveryCanceled';
136
        $this->labelStatus[0]  = 'StatusDeliveryDraft';
137
        $this->labelStatus[1]  = 'StatusDeliveryValidated';
138
    }
139
140
    /**
141
     *  Create delivery receipt in database
142
     *
143
     *  @param  User    $user       Object du user qui cree
144
     *  @return int                 Return integer <0 si erreur, id delivery cree si ok
145
     */
146
    public function create($user)
147
    {
148
        global $conf;
149
150
        dol_syslog("Delivery::create");
151
152
        if (empty($this->model_pdf)) {
153
            $this->model_pdf = getDolGlobalString('DELIVERY_ADDON_PDF');
154
        }
155
156
        $error = 0;
157
158
        $now = dol_now();
159
160
        /* Delivery note as draft On positionne en mode draft le bon de livraison */
161
        $this->draft = 1;
162
163
        $this->user = $user;
164
165
        $this->db->begin();
166
167
        $sql = "INSERT INTO " . MAIN_DB_PREFIX . "delivery (";
168
        $sql .= "ref";
169
        $sql .= ", entity";
170
        $sql .= ", fk_soc";
171
        $sql .= ", ref_customer";
172
        $sql .= ", date_creation";
173
        $sql .= ", fk_user_author";
174
        $sql .= ", date_delivery";
175
        $sql .= ", fk_address";
176
        $sql .= ", note_private";
177
        $sql .= ", note_public";
178
        $sql .= ", model_pdf";
179
        $sql .= ", fk_incoterms, location_incoterms";
180
        $sql .= ") VALUES (";
181
        $sql .= "'(PROV)'";
182
        $sql .= ", " . ((int) $conf->entity);
183
        $sql .= ", " . ((int) $this->socid);
184
        $sql .= ", '" . $this->db->escape($this->ref_customer) . "'";
185
        $sql .= ", '" . $this->db->idate($now) . "'";
186
        $sql .= ", " . ((int) $user->id);
187
        $sql .= ", " . ($this->date_delivery ? "'" . $this->db->idate($this->date_delivery) . "'" : "null");
188
        $sql .= ", " . ($this->fk_delivery_address > 0 ? $this->fk_delivery_address : "null");
189
        $sql .= ", " . (!empty($this->note_private) ? "'" . $this->db->escape($this->note_private) . "'" : "null");
190
        $sql .= ", " . (!empty($this->note_public) ? "'" . $this->db->escape($this->note_public) . "'" : "null");
191
        $sql .= ", " . (!empty($this->model_pdf) ? "'" . $this->db->escape($this->model_pdf) . "'" : "null");
192
        $sql .= ", " . (int) $this->fk_incoterms;
193
        $sql .= ", '" . $this->db->escape($this->location_incoterms) . "'";
194
        $sql .= ")";
195
196
        dol_syslog("Delivery::create", LOG_DEBUG);
197
        $resql = $this->db->query($sql);
198
        if ($resql) {
199
            $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "delivery");
200
201
            $numref = "(PROV" . $this->id . ")";
202
203
            $sql = "UPDATE " . MAIN_DB_PREFIX . "delivery ";
204
            $sql .= "SET ref = '" . $this->db->escape($numref) . "'";
205
            $sql .= " WHERE rowid = " . ((int) $this->id);
206
207
            dol_syslog("Delivery::create", LOG_DEBUG);
208
            $resql = $this->db->query($sql);
209
            if ($resql) {
210
                if (!getDolGlobalInt('MAIN_SUBMODULE_EXPEDITION')) {
211
                    $commande = new Commande($this->db);
212
                    $commande->id = $this->commande_id;
213
                    $commande->fetch_lines();
214
                }
215
216
217
                /*
218
                 *  Inserting products into the database
219
                 */
220
                $num = count($this->lines);
221
                for ($i = 0; $i < $num; $i++) {
222
                    $origin_id = $this->lines[$i]->origin_line_id;
223
                    if (!$origin_id) {
224
                        $origin_id = $this->lines[$i]->commande_ligne_id; // For backward compatibility
225
                    }
226
227
                    if (!$this->create_line($origin_id, $this->lines[$i]->qty, $this->lines[$i]->fk_product, $this->lines[$i]->description, $this->lines[$i]->array_options)) {
228
                        $error++;
229
                    }
230
                }
231
232
                if (!$error && $this->id && $this->origin_id) {
233
                    $ret = $this->add_object_linked();
234
                    if (!$ret) {
235
                        $error++;
236
                    }
237
238
                    if (!getDolGlobalInt('MAIN_SUBMODULE_EXPEDITION')) {
239
                        $ret = $this->setStatut(2, $this->origin_id, $this->origin);
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$origin has been deprecated: Use $origin_type and $origin_id instead. ( Ignorable by Annotation )

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

239
                        $ret = $this->setStatut(2, $this->origin_id, /** @scrutinizer ignore-deprecated */ $this->origin);

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...
240
                        if (!$ret) {
241
                            $error++;
242
                        }
243
                    }
244
                }
245
246
                if (!$error) {
247
                    $this->db->commit();
248
                    return $this->id;
249
                } else {
250
                    $error++;
251
                    $this->error = $this->db->lasterror() . " - sql=" . $this->db->lastqueryerror;
252
                    $this->db->rollback();
253
                    return -3;
254
                }
255
            } else {
256
                $error++;
257
                $this->error = $this->db->lasterror() . " - sql=" . $this->db->lastqueryerror;
258
                $this->db->rollback();
259
                return -2;
260
            }
261
        } else {
262
            $error++;
263
            $this->error = $this->db->lasterror() . " - sql=" . $this->db->lastqueryerror;
264
            $this->db->rollback();
265
            return -1;
266
        }
267
    }
268
269
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
270
    /**
271
     *  Create a line
272
     *
273
     *  @param  string  $origin_id              Id of order
274
     *  @param  string  $qty                    Quantity
275
     *  @param  string  $fk_product             Id of predefined product
276
     *  @param  string  $description            Description
277
     *  @param  array   $array_options          Array options
278
     *  @return int                             Return integer <0 if KO, >0 if OK
279
     */
280
    public function create_line($origin_id, $qty, $fk_product, $description, $array_options = [])
281
    {
282
		// phpcs:enable
283
        $error = 0;
284
        $idprod = $fk_product;
285
286
        $sql = "INSERT INTO " . MAIN_DB_PREFIX . "deliverydet (fk_delivery, fk_origin_line,";
287
        $sql .= " fk_product, description, qty)";
288
        $sql .= " VALUES (" . $this->id . "," . ((int) $origin_id) . ",";
289
        $sql .= " " . ($idprod > 0 ? ((int) $idprod) : "null") . ",";
290
        $sql .= " " . ($description ? "'" . $this->db->escape($description) . "'" : "null") . ",";
291
        $sql .= (price2num($qty, 'MS')) . ")";
292
293
        dol_syslog(get_only_class($this) . "::create_line", LOG_DEBUG);
294
        if (!$this->db->query($sql)) {
295
            $error++;
296
        }
297
298
        $id = $this->db->last_insert_id(MAIN_DB_PREFIX . "deliverydet");
299
300
        if (is_array($array_options) && count($array_options) > 0) {
301
            $line = new DeliveryLine($this->db);
302
            $line->id = $id;
303
            $line->array_options = $array_options;
304
            $result = $line->insertExtraFields();
305
        }
306
307
        if (!$error) {
308
            return 1;
309
        }
310
311
        return -1;
312
    }
313
314
    /**
315
     *  Load a delivery receipt
316
     *
317
     *  @param  int     $id         Id of object to load
318
     *  @return integer
319
     */
320
    public function fetch($id)
321
    {
322
        $sql = "SELECT l.rowid, l.fk_soc, l.date_creation, l.date_valid, l.ref, l.ref_customer, l.fk_user_author,";
323
        $sql .= " l.total_ht, l.fk_statut, l.fk_user_valid, l.note_private, l.note_public";
324
        $sql .= ", l.date_delivery, l.fk_address, l.model_pdf";
325
        $sql .= ", el.fk_source as origin_id, el.sourcetype as origin";
326
        $sql .= ', l.fk_incoterms, l.location_incoterms';
327
        $sql .= ", i.libelle as label_incoterms";
328
        $sql .= " FROM " . MAIN_DB_PREFIX . "delivery as l";
329
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "element_element as el ON el.fk_target = l.rowid AND el.targettype = '" . $this->db->escape($this->element) . "'";
330
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_incoterms as i ON l.fk_incoterms = i.rowid';
331
        $sql .= " WHERE l.rowid = " . ((int) $id);
332
333
        dol_syslog(get_only_class($this) . "::fetch", LOG_DEBUG);
334
        $result = $this->db->query($sql);
335
        if ($result) {
336
            if ($this->db->num_rows($result)) {
337
                $obj = $this->db->fetch_object($result);
338
339
                $this->id                   = $obj->rowid;
340
                $this->date_delivery        = $this->db->jdate($obj->date_delivery);
341
                $this->date_creation        = $this->db->jdate($obj->date_creation);
342
                $this->date_valid           = $this->db->jdate($obj->date_valid);
343
                $this->ref                  = $obj->ref;
344
                $this->ref_customer         = $obj->ref_customer;
345
                $this->socid                = $obj->fk_soc;
346
                $this->statut               = $obj->fk_statut;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

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

346
                /** @scrutinizer ignore-deprecated */ $this->statut               = $obj->fk_statut;

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...
347
                $this->status               = $obj->fk_statut;
348
                $this->user_author_id       = $obj->fk_user_author;
349
                $this->user_validation_id   = $obj->fk_user_valid;
350
                $this->fk_delivery_address  = $obj->fk_address;
351
                $this->note                 = $obj->note_private; //TODO deprecated
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

351
                /** @scrutinizer ignore-deprecated */ $this->note                 = $obj->note_private; //TODO deprecated

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

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

Loading history...
352
                $this->note_private         = $obj->note_private;
353
                $this->note_public          = $obj->note_public;
354
                $this->model_pdf            = $obj->model_pdf;
355
                $this->origin               = $obj->origin; // May be 'shipping'
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$origin has been deprecated: Use $origin_type and $origin_id instead. ( Ignorable by Annotation )

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

355
                /** @scrutinizer ignore-deprecated */ $this->origin               = $obj->origin; // May be 'shipping'

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...
356
                $this->origin_id            = $obj->origin_id; // May be id of shipping
357
358
                //Incoterms
359
                $this->fk_incoterms = $obj->fk_incoterms;
360
                $this->location_incoterms = $obj->location_incoterms;
361
                $this->label_incoterms = $obj->label_incoterms;
362
                $this->db->free($result);
363
364
                if ($this->statut == 0) {
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

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

364
                if (/** @scrutinizer ignore-deprecated */ $this->statut == 0) {

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...
365
                    $this->draft = 1;
366
                }
367
368
                // Retrieve all extrafields
369
                // fetch optionals attributes and labels
370
                $this->fetch_optionals();
371
372
                // Load lines
373
                $result = $this->fetch_lines();
374
                if ($result < 0) {
375
                    return -3;
376
                }
377
378
                return 1;
379
            } else {
380
                $this->error = 'Delivery with id ' . $id . ' not found sql=' . $sql;
381
                dol_syslog(get_only_class($this) . '::fetch Error ' . $this->error, LOG_ERR);
382
                return -2;
383
            }
384
        } else {
385
            $this->error = $this->db->error();
386
            return -1;
387
        }
388
    }
389
390
    /**
391
     *  Validate object and update stock if option enabled
392
     *
393
     *  @param  User    $user       Object user that validate
394
     *  @param  int     $notrigger  1=Does not execute triggers, 0= execute triggers
395
     *  @return int
396
     */
397
    public function valid($user, $notrigger = 0)
398
    {
399
        global $conf;
400
401
        require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/files.lib.php';
402
403
        dol_syslog(get_only_class($this) . "::valid begin");
404
405
        $this->db->begin();
406
407
        $error = 0;
408
409
        if (
410
            (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('expedition', 'delivery', 'creer'))
411
            || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('expedition', 'delivery_advance', 'validate'))
412
        ) {
413
            if (getDolGlobalString('DELIVERY_ADDON_NUMBER')) {
414
                // Setting the command numbering module name
415
                $modName = getDolGlobalString('DELIVERY_ADDON_NUMBER');
416
417
                if (is_readable(DOL_DOCUMENT_ROOT . '/core/modules/delivery/' . $modName . '.php')) {
418
                    require_once constant('DOL_DOCUMENT_ROOT') . '/core/modules/delivery/' . $modName . '.php';
419
420
                    $now = dol_now();
421
422
                    // Retrieving the new reference
423
                    $objMod = new $modName($this->db);
424
                    $soc = new Societe($this->db);
425
                    $soc->fetch($this->socid);
426
427
                    if (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref)) { // empty should not happened, but when it occurs, the test save life
428
                        $numref = $objMod->delivery_get_num($soc, $this);
429
                    } else {
430
                        $numref = $this->ref;
431
                    }
432
                    $this->newref = dol_sanitizeFileName($numref);
433
434
                    // Test if is not already in valid status. If so, we stop to avoid decrementing the stock twice.
435
                    $sql = "SELECT ref";
436
                    $sql .= " FROM " . MAIN_DB_PREFIX . "delivery";
437
                    $sql .= " WHERE ref = '" . $this->db->escape($numref) . "'";
438
                    $sql .= " AND fk_statut <> 0";
439
                    $sql .= " AND entity = " . ((int) $conf->entity);
440
441
                    $resql = $this->db->query($sql);
442
                    if ($resql) {
443
                        $num = $this->db->num_rows($resql);
444
                        if ($num > 0) {
445
                            return 0;
446
                        }
447
                    }
448
449
                    $sql = "UPDATE " . MAIN_DB_PREFIX . "delivery SET";
450
                    $sql .= " ref='" . $this->db->escape($numref) . "'";
451
                    $sql .= ", fk_statut = 1";
452
                    $sql .= ", date_valid = '" . $this->db->idate($now) . "'";
453
                    $sql .= ", fk_user_valid = " . $user->id;
454
                    $sql .= " WHERE rowid = " . ((int) $this->id);
455
                    $sql .= " AND fk_statut = 0";
456
457
                    $resql = $this->db->query($sql);
458
                    if (!$resql) {
459
                        dol_print_error($this->db);
460
                        $this->error = $this->db->lasterror();
461
                        $error++;
462
                    }
463
464
                    if (!$error && !$notrigger) {
465
                        // Call trigger
466
                        $result = $this->call_trigger('DELIVERY_VALIDATE', $user);
467
                        if ($result < 0) {
468
                            $error++;
469
                        }
470
                        // End call triggers
471
                    }
472
473
                    if (!$error) {
474
                        $this->oldref = $this->ref;
475
476
                        // Rename directory if dir was a temporary ref
477
                        if (preg_match('/^[\(]?PROV/i', $this->ref)) {
478
                            // Now we rename also files into index
479
                            $sql = 'UPDATE ' . MAIN_DB_PREFIX . "ecm_files set filename = CONCAT('" . $this->db->escape($this->newref) . "', SUBSTR(filename, " . (strlen($this->ref) + 1) . ")), filepath = 'expedition/receipt/" . $this->db->escape($this->newref) . "'";
480
                            $sql .= " WHERE filename LIKE '" . $this->db->escape($this->ref) . "%' AND filepath = 'expedition/receipt/" . $this->db->escape($this->ref) . "' and entity = " . ((int) $conf->entity);
481
                            $resql = $this->db->query($sql);
482
                            if (!$resql) {
483
                                $error++;
484
                                $this->error = $this->db->lasterror();
485
                            }
486
                            $sql = 'UPDATE ' . MAIN_DB_PREFIX . "ecm_files set filepath = 'expedition/receipt/" . $this->db->escape($this->newref) . "'";
487
                            $sql .= " WHERE filepath = 'expedition/receipt/" . $this->db->escape($this->ref) . "' and entity = " . $conf->entity;
488
                            $resql = $this->db->query($sql);
489
                            if (!$resql) {
490
                                $error++;
491
                                $this->error = $this->db->lasterror();
492
                            }
493
494
                            // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
495
                            $oldref = dol_sanitizeFileName($this->ref);
496
                            $newref = dol_sanitizeFileName($numref);
497
                            $dirsource = $conf->expedition->dir_output . '/receipt/' . $oldref;
498
                            $dirdest = $conf->expedition->dir_output . '/receipt/' . $newref;
499
                            if (!$error && file_exists($dirsource)) {
500
                                dol_syslog(get_only_class($this) . "::valid rename dir " . $dirsource . " into " . $dirdest);
501
502
                                if (@rename($dirsource, $dirdest)) {
503
                                    dol_syslog("Rename ok");
504
                                    // Rename docs starting with $oldref with $newref
505
                                    $listoffiles = dol_dir_list($conf->expedition->dir_output . '/receipt/' . $newref, 'files', 1, '^' . preg_quote($oldref, '/'));
506
                                    foreach ($listoffiles as $fileentry) {
507
                                        $dirsource = $fileentry['name'];
508
                                        $dirdest = preg_replace('/^' . preg_quote($oldref, '/') . '/', $newref, $dirsource);
509
                                        $dirsource = $fileentry['path'] . '/' . $dirsource;
510
                                        $dirdest = $fileentry['path'] . '/' . $dirdest;
511
                                        @rename($dirsource, $dirdest);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for rename(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

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

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

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

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
512
                                    }
513
                                }
514
                            }
515
                        }
516
517
                        // Set new ref and current status
518
                        if (!$error) {
519
                            $this->ref = $numref;
520
                            $this->statut = 1;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

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

520
                            /** @scrutinizer ignore-deprecated */ $this->statut = 1;

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...
521
                        }
522
523
                        dol_syslog(get_only_class($this) . "::valid ok");
524
                    }
525
526
                    if (!$error) {
527
                        $this->db->commit();
528
                        return 1;
529
                    } else {
530
                        $this->db->rollback();
531
                        return -1;
532
                    }
533
                }
534
            }
535
536
            return -1;
537
        } else {
538
            $this->error = "NotAllowed";
539
            dol_syslog(get_only_class($this) . "::valid " . $this->error, LOG_ERR);
540
            return -1;
541
        }
542
    }
543
544
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
545
    /**
546
     *  Creating the delivery slip from an existing shipment
547
     *
548
     *  @param  User    $user           User who creates
549
     *  @param  int     $sending_id     Id of the expedition that serves as a model
550
     *  @return integer                 Return integer <=0 if KO, >0 if OK
551
     */
552
    public function create_from_sending($user, $sending_id)
553
    {
554
		// phpcs:enable
555
        global $conf;
556
557
        $expedition = new Expedition($this->db);
558
        $result = $expedition->fetch($sending_id);
559
        if ($result <= 0) {
560
            return $result;
561
        }
562
563
        $this->lines = array();
564
565
        $num = count($expedition->lines);
566
        for ($i = 0; $i < $num; $i++) {
567
            $line = new DeliveryLine($this->db);
568
            $line->origin_line_id    = $expedition->lines[$i]->origin_line_id;
569
            $line->label             = $expedition->lines[$i]->label;
570
            $line->description       = $expedition->lines[$i]->description;
571
            $line->qty               = $expedition->lines[$i]->qty_shipped;
572
            $line->fk_product        = $expedition->lines[$i]->fk_product;
573
            if (!getDolGlobalString('MAIN_EXTRAFIELDS_DISABLED') && is_array($expedition->lines[$i]->array_options) && count($expedition->lines[$i]->array_options) > 0) { // For avoid conflicts if trigger used
574
                $line->array_options = $expedition->lines[$i]->array_options;
575
            }
576
            $this->lines[$i] = $line;
577
        }
578
579
        $this->origin               = $expedition->element;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$origin has been deprecated: Use $origin_type and $origin_id instead. ( Ignorable by Annotation )

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

579
        /** @scrutinizer ignore-deprecated */ $this->origin               = $expedition->element;

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...
580
        $this->origin_id            = $expedition->id;
581
        $this->note_private         = $expedition->note_private;
582
        $this->note_public          = $expedition->note_public;
583
        $this->fk_project           = $expedition->fk_project;
584
        $this->date_delivery        = $expedition->date_delivery;
585
        $this->fk_delivery_address  = $expedition->fk_delivery_address;
586
        $this->socid                = $expedition->socid;
587
        $this->ref_customer         = $expedition->ref_customer;
588
589
        //Incoterms
590
        $this->fk_incoterms = $expedition->fk_incoterms;
591
        $this->location_incoterms = $expedition->location_incoterms;
592
593
        return $this->create($user);
594
    }
595
596
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
597
    /**
598
     * Update a livraison line (only extrafields)
599
     *
600
     * @param   int     $id                 Id of line (livraison line)
601
     * @param   array   $array_options      extrafields array
602
     * @return  int                         Return integer <0 if KO, >0 if OK
603
     */
604
    public function update_line($id, $array_options = [])
605
    {
606
		// phpcs:enable
607
        global $conf;
608
        $error = 0;
609
610
        if ($id > 0 && !$error && !getDolGlobalString('MAIN_EXTRAFIELDS_DISABLED') && is_array($array_options) && count($array_options) > 0) { // For avoid conflicts if trigger used
611
            $line = new DeliveryLine($this->db);
612
            $line->array_options = $array_options;
613
            $line->id = $id;
614
            $result = $line->insertExtraFields();
615
616
            if ($result < 0) {
617
                $this->errors[] = $line->error;
618
                $error++;
619
            }
620
        }
621
622
        if (!$error) {
623
            return 1;
624
        } else {
625
            return -1;
626
        }
627
    }
628
629
630
    /**
631
     *  Add line
632
     *
633
     *  @param  int     $origin_id              Origin id
634
     *  @param  float   $qty                    Qty
635
     *  @param  array   $array_options          Array options
636
     *  @return void
637
     */
638
    public function addline($origin_id, $qty, $array_options = [])
639
    {
640
        global $conf;
641
642
        $num = count($this->lines);
643
        $line = new DeliveryLine($this->db);
644
645
        $line->origin_id = $origin_id;
646
        $line->qty = $qty;
647
        if (!getDolGlobalString('MAIN_EXTRAFIELDS_DISABLED') && is_array($array_options) && count($array_options) > 0) { // For avoid conflicts if trigger used
648
            $line->array_options = $array_options;
649
        }
650
        $this->lines[$num] = $line;
651
    }
652
653
    /**
654
     *  Delete line
655
     *
656
     *  @param  int     $lineid     Line id
657
     *  @return integer             Return integer <0 if KO, 0 if nothing done, >0 if OK
658
     */
659
    public function deleteLine($lineid)
660
    {
661
        if ($this->statut == 0) {
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

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

661
        if (/** @scrutinizer ignore-deprecated */ $this->statut == 0) {

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...
662
            $sql = "DELETE FROM " . MAIN_DB_PREFIX . "commandedet";
663
            $sql .= " WHERE rowid = " . ((int) $lineid);
664
665
            if ($this->db->query($sql)) {
666
                $this->update_price(1);
667
668
                return 1;
669
            } else {
670
                return -1;
671
            }
672
        }
673
674
        return 0;
675
    }
676
677
    /**
678
     * Delete object
679
     *
680
     * @param   User        $user       User making the deletion
681
     * @return  integer
682
     */
683
    public function delete($user = null)
684
    {
685
        global $conf, $langs;
686
687
        require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/files.lib.php';
688
689
        $this->db->begin();
690
691
        $error = 0;
692
693
        $sql = "DELETE FROM " . MAIN_DB_PREFIX . "deliverydet";
694
        $sql .= " WHERE fk_delivery = " . ((int) $this->id);
695
        if ($this->db->query($sql)) {
696
            // Delete linked object
697
            $res = $this->deleteObjectLinked();
698
            if ($res < 0) {
699
                $error++;
700
            }
701
702
            if (!$error) {
703
                $sql = "DELETE FROM " . MAIN_DB_PREFIX . "delivery";
704
                $sql .= " WHERE rowid = " . ((int) $this->id);
705
                if ($this->db->query($sql)) {
706
                    $this->db->commit();
707
708
                    // Deleting pdf folder's draft On efface le repertoire de pdf provisoire
709
                    $ref = dol_sanitizeFileName($this->ref);
710
                    if (!empty($conf->expedition->dir_output)) {
711
                        $dir = $conf->expedition->dir_output . '/receipt/' . $ref;
712
                        $file = $dir . '/' . $ref . '.pdf';
713
                        if (file_exists($file)) {
714
                            if (!dol_delete_file($file)) {
715
                                return 0;
716
                            }
717
                        }
718
                        if (file_exists($dir)) {
719
                            if (!dol_delete_dir($dir)) {
720
                                $this->error = $langs->trans("ErrorCanNotDeleteDir", $dir);
721
                                return 0;
722
                            }
723
                        }
724
                    }
725
726
                    // Call trigger
727
                    $result = $this->call_trigger('DELIVERY_DELETE', $user);
728
                    if ($result < 0) {
729
                        $this->db->rollback();
730
                        return -4;
731
                    }
732
                    // End call triggers
733
734
                    return 1;
735
                } else {
736
                    $this->error = $this->db->lasterror() . " - sql=$sql";
737
                    $this->db->rollback();
738
                    return -3;
739
                }
740
            } else {
741
                $this->error = $this->db->lasterror() . " - sql=$sql";
742
                $this->db->rollback();
743
                return -2;
744
            }
745
        } else {
746
            $this->error = $this->db->lasterror() . " - sql=$sql";
747
            $this->db->rollback();
748
            return -1;
749
        }
750
    }
751
752
    /**
753
     * getTooltipContentArray
754
     * @param array $params params to construct tooltip data
755
     * @since v18
756
     * @return array
757
     */
758
    public function getTooltipContentArray($params)
759
    {
760
        global $langs;
761
762
        $langs->load('deliveries');
763
764
        $datas = [];
765
766
        $datas['picto'] = img_picto('', $this->picto) . ' <u>' . $langs->trans("ShowReceiving") . '</u>:<br>';
767
        $datas['picto'] .= '<b>' . $langs->trans("Status") . '</b>: ' . $this->ref;
768
769
        return $datas;
770
    }
771
772
    /**
773
     *  Return clicable name (with picto eventually)
774
     *
775
     *  @param  int     $withpicto                  0=No picto, 1=Include picto into link, 2=Only picto
776
     *  @param  int     $save_lastsearch_value      -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
777
     *  @return string                              Chaine avec URL
778
     */
779
    public function getNomUrl($withpicto = 0, $save_lastsearch_value = -1)
780
    {
781
        global $langs, $hookmanager;
782
783
        $result = '';
784
785
        $params = [
786
            'id' => $this->id,
787
            'objecttype' => $this->element,
788
        ];
789
        $classfortooltip = 'classfortooltip';
790
        $dataparams = '';
791
        if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
792
            $classfortooltip = 'classforajaxtooltip';
793
            $dataparams = ' data-params="' . dol_escape_htmltag(json_encode($params)) . '"';
794
            $label = '';
795
        } else {
796
            $label = implode($this->getTooltipContentArray($params));
797
        }
798
799
        $url = constant('BASE_URL') . '/delivery/card.php?id=' . $this->id;
800
801
        //if ($option !== 'nolink')
802
        //{
803
        // Add param to save lastsearch_values or not
804
        $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
805
        if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
806
            $add_save_lastsearch_values = 1;
807
        }
808
        if ($add_save_lastsearch_values) {
809
            $url .= '&save_lastsearch_values=1';
810
        }
811
        //}
812
813
        $linkstart = '<a href="' . $url . '"';
814
        $linkstart .= ($label ? ' title="' . dol_escape_htmltag($label, 1) . '"' : ' title="tocomplete"');
815
        $linkstart .= $dataparams . ' class="' . $classfortooltip . '">';
816
        $linkend = '</a>';
817
818
        if ($withpicto) {
819
            $result .= ($linkstart . img_object($label, $this->picto, $dataparams . ' class="' . $classfortooltip . '"') . $linkend);
820
        }
821
        if ($withpicto && $withpicto != 2) {
822
            $result .= ' ';
823
        }
824
        $result .= $linkstart . $this->ref . $linkend;
825
826
        global $action;
827
        $hookmanager->initHooks(array($this->element . 'dao'));
828
        $parameters = array('id' => $this->id, 'getnomurl' => &$result);
829
        $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
830
        if ($reshook > 0) {
831
            $result = $hookmanager->resPrint;
832
        } else {
833
            $result .= $hookmanager->resPrint;
834
        }
835
        return $result;
836
    }
837
838
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
839
    /**
840
     *  Load lines insto $this->lines.
841
     *
842
     *  @return     int                             Return integer <0 if KO, >0 if OK
843
     */
844
    public function fetch_lines()
845
    {
846
		// phpcs:enable
847
        $this->lines = array();
848
849
        $sql = "SELECT ld.rowid, ld.fk_product, ld.description, ld.subprice, ld.total_ht, ld.qty as qty_shipped, ld.fk_origin_line, ";
850
        $sql .= " cd.qty as qty_asked, cd.label as custom_label, cd.fk_unit,";
851
        $sql .= " p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc,";
852
        $sql .= " p.weight, p.weight_units,  p.width, p.width_units, p.length, p.length_units, p.height, p.height_units, p.surface, p.surface_units, p.volume, p.volume_units, p.tobatch as product_tobatch";
853
        $sql .= " FROM " . MAIN_DB_PREFIX . "commandedet as cd, " . MAIN_DB_PREFIX . "deliverydet as ld";
854
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product as p on p.rowid = ld.fk_product";
855
        $sql .= " WHERE ld.fk_origin_line = cd.rowid";
856
        $sql .= " AND ld.fk_delivery = " . ((int) $this->id);
857
858
        dol_syslog(get_only_class($this) . "::fetch_lines", LOG_DEBUG);
859
        $resql = $this->db->query($sql);
860
        if ($resql) {
861
            $num = $this->db->num_rows($resql);
862
            $i = 0;
863
            while ($i < $num) {
864
                $obj = $this->db->fetch_object($resql);
865
866
                $line = new DeliveryLine($this->db);
867
868
                $line->id = $obj->rowid;
869
                $line->label = $obj->custom_label;
870
                $line->description  = $obj->description;
871
                $line->fk_product   = $obj->fk_product;
872
                $line->qty_asked    = $obj->qty_asked;
873
                $line->qty_shipped  = $obj->qty_shipped;
874
875
                $line->product_label    = $obj->product_label; // Product label
876
                $line->product_ref      = $obj->product_ref; // Product ref
877
                $line->product_desc     = $obj->product_desc; // Product description
878
                $line->product_type     = $obj->fk_product_type;
879
880
                $line->fk_origin_line = $obj->fk_origin_line;
881
882
                $line->price = $obj->subprice;
883
                $line->total_ht = $obj->total_ht;
884
885
                // units
886
                $line->weight           = $obj->weight;
887
                $line->weight_units     = $obj->weight_units;
888
                $line->width            = $obj->width;
889
                $line->width_units      = $obj->width_units;
890
                $line->height           = $obj->height;
891
                $line->height_units     = $obj->height_units;
892
                $line->length           = $obj->length;
893
                $line->length_units     = $obj->length_units;
894
                $line->surface          = $obj->surface;
895
                $line->surface_units = $obj->surface_units;
896
                $line->volume           = $obj->volume;
897
                $line->volume_units     = $obj->volume_units;
898
899
                $line->fk_unit = $obj->fk_unit;
900
                $line->fetch_optionals();
901
902
                $this->lines[$i] = $line;
903
904
                $i++;
905
            }
906
            $this->db->free($resql);
907
908
            return 1;
909
        } else {
910
            return -1;
911
        }
912
    }
913
914
915
    /**
916
     *  Return the label of the status
917
     *
918
     *  @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
919
     *  @return string                 Label of status
920
     */
921
    public function getLibStatut($mode = 0)
922
    {
923
        return $this->LibStatut($this->statut, $mode);
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

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

923
        return $this->LibStatut(/** @scrutinizer ignore-deprecated */ $this->statut, $mode);

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...
924
    }
925
926
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
927
    /**
928
     *  Return the label of a given status
929
     *
930
     *  @param  int     $status        Id status
931
     *  @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
932
     *  @return string                 Label of status
933
     */
934
    public function LibStatut($status, $mode)
935
    {
936
		// phpcs:enable
937
        global $langs;
938
939
        if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
940
            global $langs;
941
            //$langs->load("mymodule");
942
            $this->labelStatus[-1] = $langs->transnoentitiesnoconv('StatusDeliveryCanceled');
943
            $this->labelStatus[0] = $langs->transnoentitiesnoconv('StatusDeliveryDraft');
944
            $this->labelStatus[1] = $langs->transnoentitiesnoconv('StatusDeliveryValidated');
945
            $this->labelStatusShort[-1] = $langs->transnoentitiesnoconv('StatusDeliveryCanceled');
946
            $this->labelStatusShort[0] = $langs->transnoentitiesnoconv('StatusDeliveryDraft');
947
            $this->labelStatusShort[1] = $langs->transnoentitiesnoconv('StatusDeliveryValidated');
948
        }
949
950
        $statusType = 'status0';
951
        if ($status == -1) {
952
            $statusType = 'status5';
953
        }
954
        if ($status == 1) {
955
            $statusType = 'status4';
956
        }
957
958
        return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
959
    }
960
961
962
    /**
963
     *  Initialise an instance with random values.
964
     *  Used to build previews or test instances.
965
     *  id must be 0 if object instance is a specimen.
966
     *
967
     *  @return int
968
     */
969
    public function initAsSpecimen()
970
    {
971
        $now = dol_now();
972
973
        // Load array of products prodids
974
        $num_prods = 0;
975
        $prodids = array();
976
        $sql = "SELECT rowid";
977
        $sql .= " FROM " . MAIN_DB_PREFIX . "product";
978
        $sql .= " WHERE entity IN (" . getEntity('product') . ")";
979
        $sql .= " AND tosell = 1";
980
        $sql .= $this->db->plimit(100);
981
982
        $resql = $this->db->query($sql);
983
        if ($resql) {
984
            $num_prods = $this->db->num_rows($resql);
985
            $i = 0;
986
            while ($i < $num_prods) {
987
                $i++;
988
                $row = $this->db->fetch_row($resql);
989
                $prodids[$i] = $row[0];
990
            }
991
        }
992
993
        // Initialise parameters
994
        $this->id = 0;
995
        $this->ref = 'SPECIMEN';
996
        $this->specimen = 1;
997
        $this->socid = 1;
998
        $this->date_delivery = $now;
999
        $this->note_public = 'Public note';
1000
        $this->note_private = 'Private note';
1001
1002
        $i = 0;
1003
        $line = new DeliveryLine($this->db);
1004
        $line->fk_product     = reset($prodids);
1005
        $line->qty_asked      = 10;
1006
        $line->qty_shipped    = 9;
1007
        $line->ref            = 'REFPROD';
1008
        $line->label          = 'Specimen';
1009
        $line->description    = 'Description';
1010
        $line->price          = 100;
1011
        $line->total_ht       = 100;
1012
1013
        $this->lines[$i] = $line;
1014
1015
        return 1;
1016
    }
1017
1018
    /**
1019
     *  Renvoie la quantite de produit restante a livrer pour une commande
1020
     *
1021
     *  @return     array|int       Product remaining to be delivered or <0 if KO
1022
     *  TODO use new function
1023
     */
1024
    public function getRemainingDelivered()
1025
    {
1026
        // Get the linked object
1027
        $this->fetchObjectLinked('', '', $this->id, $this->element);
1028
        //var_dump($this->linkedObjectsIds);
1029
        // Get the product ref and qty in source
1030
        $sqlSourceLine = "SELECT st.rowid, st.description, st.qty";
1031
        $sqlSourceLine .= ", p.ref, p.label";
1032
        $sqlSourceLine .= " FROM " . MAIN_DB_PREFIX . $this->linkedObjectsIds[0]['type'] . "det as st";
1033
        $sqlSourceLine .= " LEFT JOIN " . MAIN_DB_PREFIX . "product as p ON st.fk_product = p.rowid";
1034
        $sqlSourceLine .= " WHERE fk_" . $this->linked_objects[0]['type'] . " = " . ((int) $this->linked_objects[0]['linkid']);
1035
1036
        $resultSourceLine = $this->db->query($sqlSourceLine);
1037
        if ($resultSourceLine) {
1038
            $num_lines = $this->db->num_rows($resultSourceLine);
1039
            $i = 0;
1040
            $array = array();
1041
            while ($i < $num_lines) {
1042
                $objSourceLine = $this->db->fetch_object($resultSourceLine);
1043
1044
                // Get lines of sources already delivered
1045
                $sql = "SELECT ld.fk_origin_line, sum(ld.qty) as qty";
1046
                $sql .= " FROM " . MAIN_DB_PREFIX . "deliverydet as ld, " . MAIN_DB_PREFIX . "delivery as l,";
1047
                $sql .= " " . MAIN_DB_PREFIX . $this->linked_objects[0]['type'] . " as c";
1048
                $sql .= ", " . MAIN_DB_PREFIX . $this->linked_objects[0]['type'] . "det as cd";
1049
                $sql .= " WHERE ld.fk_delivery = l.rowid";
1050
                $sql .= " AND ld.fk_origin_line = cd.rowid";
1051
                $sql .= " AND cd.fk_" . $this->linked_objects[0]['type'] . " = c.rowid";
1052
                $sql .= " AND cd.fk_" . $this->linked_objects[0]['type'] . " = " . ((int) $this->linked_objects[0]['linkid']);
1053
                $sql .= " AND ld.fk_origin_line = " . ((int) $objSourceLine->rowid);
1054
                $sql .= " GROUP BY ld.fk_origin_line";
1055
1056
                $result = $this->db->query($sql);
1057
                $row = $this->db->fetch_row($result);
1058
1059
                if ($objSourceLine->qty - $row[1] > 0) {
1060
                    if ($row[0] == $objSourceLine->rowid) {
1061
                        $array[$i]['qty'] = $objSourceLine->qty - $row[1];
1062
                    } else {
1063
                        $array[$i]['qty'] = $objSourceLine->qty;
1064
                    }
1065
1066
                    $array[$i]['ref'] = $objSourceLine->ref;
1067
                    $array[$i]['label'] = $objSourceLine->label ? $objSourceLine->label : $objSourceLine->description;
1068
                } elseif ($objSourceLine->qty - $row[1] < 0) {
1069
                    $array[$i]['qty'] = $objSourceLine->qty - $row[1] . " Erreur livraison !";
1070
                    $array[$i]['ref'] = $objSourceLine->ref;
1071
                    $array[$i]['label'] = $objSourceLine->label ? $objSourceLine->label : $objSourceLine->description;
1072
                }
1073
1074
                $i++;
1075
            }
1076
            return $array;
1077
        } else {
1078
            $this->error = $this->db->error() . " - sql=$sqlSourceLine";
1079
            return -1;
1080
        }
1081
    }
1082
1083
    /**
1084
     *  Set the planned delivery date
1085
     *
1086
     *  @param      User            $user               Object utilisateur qui modifie
1087
     *  @param      integer         $delivery_date     Delivery date
1088
     *  @return     int                                 Return integer <0 if KO, >0 if OK
1089
     */
1090
    public function setDeliveryDate($user, $delivery_date)
1091
    {
1092
        if ($user->hasRight('expedition', 'creer')) {
1093
            $sql = "UPDATE " . MAIN_DB_PREFIX . "delivery";
1094
            $sql .= " SET date_delivery = " . ($delivery_date ? "'" . $this->db->idate($delivery_date) . "'" : 'null');
1095
            $sql .= " WHERE rowid = " . ((int) $this->id);
1096
1097
            dol_syslog(get_only_class($this) . "::setDeliveryDate", LOG_DEBUG);
1098
            $resql = $this->db->query($sql);
1099
            if ($resql) {
1100
                $this->date_delivery = $delivery_date;
1101
                return 1;
1102
            } else {
1103
                $this->error = $this->db->error();
1104
                return -1;
1105
            }
1106
        } else {
1107
            return -2;
1108
        }
1109
    }
1110
1111
    /**
1112
     *  Create object on disk
1113
     *
1114
     *  @param     string       $modele         force le modele a utiliser ('' to not force)
1115
     *  @param     Translate    $outputlangs    Object langs to use for output
1116
     *  @param     int          $hidedetails    Hide details of lines
1117
     *  @param     int          $hidedesc       Hide description
1118
     *  @param     int          $hideref        Hide ref
1119
     *  @return    int                          0 if KO, 1 if OK
1120
     */
1121
    public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
1122
    {
1123
        global $conf, $langs;
1124
1125
        $langs->load("deliveries");
1126
        $outputlangs->load("products");
1127
1128
        if (!dol_strlen($modele)) {
1129
            $modele = 'typhon';
1130
1131
            if ($this->model_pdf) {
1132
                $modele = $this->model_pdf;
1133
            } elseif (getDolGlobalString('DELIVERY_ADDON_PDF')) {
1134
                $modele = getDolGlobalString('DELIVERY_ADDON_PDF');
1135
            }
1136
        }
1137
1138
        $modelpath = "core/modules/delivery/doc/";
1139
1140
        return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
1141
    }
1142
1143
    /**
1144
     * Function used to replace a thirdparty id with another one.
1145
     *
1146
     * @param   DoliDB  $dbs        Database handler, because function is static we name it $dbs not $db to avoid breaking coding test
1147
     * @param   int     $origin_id  Old thirdparty id
1148
     * @param   int     $dest_id    New thirdparty id
1149
     * @return  bool
1150
     */
1151
    public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
1152
    {
1153
        $tables = array(
1154
            'delivery'
1155
        );
1156
1157
        return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
1158
    }
1159
1160
    /**
1161
     * Function used to replace a product id with another one.
1162
     *
1163
     * @param DoliDB $db Database handler
1164
     * @param int $origin_id Old product id
1165
     * @param int $dest_id New product id
1166
     * @return bool
1167
     */
1168
    public static function replaceProduct(DoliDB $db, $origin_id, $dest_id)
1169
    {
1170
        $tables = array(
1171
            'deliverydet'
1172
        );
1173
1174
        return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables);
1175
    }
1176
}
1177