dolibarr  17.0.3
delivery.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2005-2014 Regis Houssin <regis.houssin@inodbox.com>
4  * Copyright (C) 2006-2007 Laurent Destailleur <eldy@users.sourceforge.net>
5  * Copyright (C) 2007 Franky Van Liedekerke <franky.van.liedekerke@telenet.be>
6  * Copyright (C) 2011-2023 Philippe Grand <philippe.grand@atoo-net.com>
7  * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
8  * Copyright (C) 2014-2015 Marcos GarcĂ­a <marcosgdf@gmail.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <https://www.gnu.org/licenses/>.
22  */
23 
30 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
31 require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/core/class/commonincoterm.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
34 if (isModEnabled("propal")) {
35  require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
36 }
37 if (isModEnabled('commande')) {
38  require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
39 }
40 
41 
45 class Delivery extends CommonObject
46 {
47  use CommonIncoterm;
48 
52  public $element = "delivery";
53 
57  public $fk_element = "fk_delivery";
58 
62  public $table_element = "delivery";
63 
67  public $table_element_line = "deliverydet";
68 
72  public $picto = 'sending';
73 
77  public $draft;
78 
82  public $socid;
83 
87  public $ref_customer;
88 
92  public $date_delivery;
93 
97  public $date_creation;
98 
102  public $date_valid;
103 
107  public $model_pdf;
108 
109  public $commande_id;
110 
111  public $lines = array();
112 
113 
119  public function __construct($db)
120  {
121  $this->db = $db;
122 
123  // List of short language codes for status
124  $this->statuts[-1] = 'StatusDeliveryCanceled';
125  $this->statuts[0] = 'StatusDeliveryDraft';
126  $this->statuts[1] = 'StatusDeliveryValidated';
127  }
128 
135  public function create($user)
136  {
137  global $conf;
138 
139  dol_syslog("Delivery::create");
140 
141  if (empty($this->model_pdf)) {
142  $this->model_pdf = $conf->global->DELIVERY_ADDON_PDF;
143  }
144 
145  $error = 0;
146 
147  $now = dol_now();
148 
149  /* Delivery note as draft On positionne en mode draft le bon de livraison */
150  $this->draft = 1;
151 
152  $this->user = $user;
153 
154  $this->db->begin();
155 
156  $sql = "INSERT INTO ".MAIN_DB_PREFIX."delivery (";
157  $sql .= "ref";
158  $sql .= ", entity";
159  $sql .= ", fk_soc";
160  $sql .= ", ref_customer";
161  $sql .= ", date_creation";
162  $sql .= ", fk_user_author";
163  $sql .= ", date_delivery";
164  $sql .= ", fk_address";
165  $sql .= ", note_private";
166  $sql .= ", note_public";
167  $sql .= ", model_pdf";
168  $sql .= ", fk_incoterms, location_incoterms";
169  $sql .= ") VALUES (";
170  $sql .= "'(PROV)'";
171  $sql .= ", ".((int) $conf->entity);
172  $sql .= ", ".((int) $this->socid);
173  $sql .= ", '".$this->db->escape($this->ref_customer)."'";
174  $sql .= ", '".$this->db->idate($now)."'";
175  $sql .= ", ".((int) $user->id);
176  $sql .= ", ".($this->date_delivery ? "'".$this->db->idate($this->date_delivery)."'" : "null");
177  $sql .= ", ".($this->fk_delivery_address > 0 ? $this->fk_delivery_address : "null");
178  $sql .= ", ".(!empty($this->note_private) ? "'".$this->db->escape($this->note_private)."'" : "null");
179  $sql .= ", ".(!empty($this->note_public) ? "'".$this->db->escape($this->note_public)."'" : "null");
180  $sql .= ", ".(!empty($this->model_pdf) ? "'".$this->db->escape($this->model_pdf)."'" : "null");
181  $sql .= ", ".(int) $this->fk_incoterms;
182  $sql .= ", '".$this->db->escape($this->location_incoterms)."'";
183  $sql .= ")";
184 
185  dol_syslog("Delivery::create", LOG_DEBUG);
186  $resql = $this->db->query($sql);
187  if ($resql) {
188  $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."delivery");
189 
190  $numref = "(PROV".$this->id.")";
191 
192  $sql = "UPDATE ".MAIN_DB_PREFIX."delivery ";
193  $sql .= "SET ref = '".$this->db->escape($numref)."'";
194  $sql .= " WHERE rowid = ".((int) $this->id);
195 
196  dol_syslog("Delivery::create", LOG_DEBUG);
197  $resql = $this->db->query($sql);
198  if ($resql) {
199  if (!$conf->expedition_bon->enabled) {
200  $commande = new Commande($this->db);
201  $commande->id = $this->commande_id;
202  $commande->fetch_lines();
203  }
204 
205 
206  /*
207  * Inserting products into the database
208  */
209  $num = count($this->lines);
210  for ($i = 0; $i < $num; $i++) {
211  $origin_id = $this->lines[$i]->origin_line_id;
212  if (!$origin_id) {
213  $origin_id = $this->lines[$i]->commande_ligne_id; // For backward compatibility
214  }
215 
216  if (!$this->create_line($origin_id, $this->lines[$i]->qty, $this->lines[$i]->fk_product, $this->lines[$i]->description, $this->lines[$i]->array_options)) {
217  $error++;
218  }
219  }
220 
221  if (!$error && $this->id && $this->origin_id) {
222  $ret = $this->add_object_linked();
223  if (!$ret) {
224  $error++;
225  }
226 
227  if (!$conf->expedition_bon->enabled) {
228  // TODO standardize status uniformiser les statuts
229  $ret = $this->setStatut(2, $this->origin_id, $this->origin);
230  if (!$ret) {
231  $error++;
232  }
233  }
234  }
235 
236  if (!$error) {
237  $this->db->commit();
238  return $this->id;
239  } else {
240  $error++;
241  $this->error = $this->db->lasterror()." - sql=".$this->db->lastqueryerror;
242  $this->db->rollback();
243  return -3;
244  }
245  } else {
246  $error++;
247  $this->error = $this->db->lasterror()." - sql=".$this->db->lastqueryerror;
248  $this->db->rollback();
249  return -2;
250  }
251  } else {
252  $error++;
253  $this->error = $this->db->lasterror()." - sql=".$this->db->lastqueryerror;
254  $this->db->rollback();
255  return -1;
256  }
257  }
258 
259  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
270  public function create_line($origin_id, $qty, $fk_product, $description, $array_options = null)
271  {
272  // phpcs:enable
273  $error = 0;
274  $idprod = $fk_product;
275  $j = 0;
276 
277  $sql = "INSERT INTO ".MAIN_DB_PREFIX."deliverydet (fk_delivery, fk_origin_line,";
278  $sql .= " fk_product, description, qty)";
279  $sql .= " VALUES (".$this->id.",".((int) $origin_id).",";
280  $sql .= " ".($idprod > 0 ? ((int) $idprod) : "null").",";
281  $sql .= " ".($description ? "'".$this->db->escape($description)."'" : "null").",";
282  $sql .= (price2num($qty, 'MS')).")";
283 
284  dol_syslog(get_class($this)."::create_line", LOG_DEBUG);
285  if (!$this->db->query($sql)) {
286  $error++;
287  }
288 
289  $id = $this->db->last_insert_id(MAIN_DB_PREFIX."deliverydet");
290 
291  if (is_array($array_options) && count($array_options) > 0) {
292  $line = new DeliveryLine($this->db);
293  $line->id = $id;
294  $line->array_options = $array_options;
295  $result = $line->insertExtraFields();
296  }
297 
298  if ($error == 0) {
299  return 1;
300  }
301  }
302 
309  public function fetch($id)
310  {
311  global $conf;
312 
313  $sql = "SELECT l.rowid, l.fk_soc, l.date_creation, l.date_valid, l.ref, l.ref_customer, l.fk_user_author,";
314  $sql .= " l.total_ht, l.fk_statut, l.fk_user_valid, l.note_private, l.note_public";
315  $sql .= ", l.date_delivery, l.fk_address, l.model_pdf";
316  $sql .= ", el.fk_source as origin_id, el.sourcetype as origin";
317  $sql .= ', l.fk_incoterms, l.location_incoterms';
318  $sql .= ", i.libelle as label_incoterms";
319  $sql .= " FROM ".MAIN_DB_PREFIX."delivery as l";
320  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON el.fk_target = l.rowid AND el.targettype = '".$this->db->escape($this->element)."'";
321  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON l.fk_incoterms = i.rowid';
322  $sql .= " WHERE l.rowid = ".((int) $id);
323 
324  dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
325  $result = $this->db->query($sql);
326  if ($result) {
327  if ($this->db->num_rows($result)) {
328  $obj = $this->db->fetch_object($result);
329 
330  $this->id = $obj->rowid;
331  $this->date_delivery = $this->db->jdate($obj->date_delivery);
332  $this->date_creation = $this->db->jdate($obj->date_creation);
333  $this->date_valid = $this->db->jdate($obj->date_valid);
334  $this->ref = $obj->ref;
335  $this->ref_customer = $obj->ref_customer;
336  $this->socid = $obj->fk_soc;
337  $this->statut = $obj->fk_statut;
338  $this->user_author_id = $obj->fk_user_author;
339  $this->user_valid_id = $obj->fk_user_valid;
340  $this->fk_delivery_address = $obj->fk_address;
341  $this->note = $obj->note_private; //TODO deprecated
342  $this->note_private = $obj->note_private;
343  $this->note_public = $obj->note_public;
344  $this->model_pdf = $obj->model_pdf;
345  $this->modelpdf = $obj->model_pdf; // deprecated
346  $this->origin = $obj->origin; // May be 'shipping'
347  $this->origin_id = $obj->origin_id; // May be id of shipping
348 
349  //Incoterms
350  $this->fk_incoterms = $obj->fk_incoterms;
351  $this->location_incoterms = $obj->location_incoterms;
352  $this->label_incoterms = $obj->label_incoterms;
353  $this->db->free($result);
354 
355  if ($this->statut == 0) {
356  $this->draft = 1;
357  }
358 
359  // Retrieve all extrafields
360  // fetch optionals attributes and labels
361  $this->fetch_optionals();
362 
363  // Load lines
364  $result = $this->fetch_lines();
365  if ($result < 0) {
366  return -3;
367  }
368 
369  return 1;
370  } else {
371  $this->error = 'Delivery with id '.$id.' not found sql='.$sql;
372  dol_syslog(get_class($this).'::fetch Error '.$this->error, LOG_ERR);
373  return -2;
374  }
375  } else {
376  $this->error = $this->db->error();
377  return -1;
378  }
379  }
380 
388  public function valid($user, $notrigger = 0)
389  {
390  global $conf, $langs;
391  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
392 
393  dol_syslog(get_class($this)."::valid begin");
394 
395  $this->db->begin();
396 
397  $error = 0;
398 
399  if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->expedition->delivery->creer))
400  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->expedition->delivery_advance->validate))) {
401  if (!empty($conf->global->DELIVERY_ADDON_NUMBER)) {
402  // Setting the command numbering module name
403  $modName = $conf->global->DELIVERY_ADDON_NUMBER;
404 
405  if (is_readable(DOL_DOCUMENT_ROOT.'/core/modules/delivery/'.$modName.'.php')) {
406  require_once DOL_DOCUMENT_ROOT.'/core/modules/delivery/'.$modName.'.php';
407 
408  $now = dol_now();
409 
410  // Retrieving the new reference
411  $objMod = new $modName($this->db);
412  $soc = new Societe($this->db);
413  $soc->fetch($this->socid);
414 
415  if (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref)) { // empty should not happened, but when it occurs, the test save life
416  $numref = $objMod->delivery_get_num($soc, $this);
417  } else {
418  $numref = $this->ref;
419  }
420  $this->newref = dol_sanitizeFileName($numref);
421 
422  // Test if is not already in valid status. If so, we stop to avoid decrementing the stock twice.
423  $sql = "SELECT ref";
424  $sql .= " FROM ".MAIN_DB_PREFIX."delivery";
425  $sql .= " WHERE ref = '".$this->db->escape($numref)."'";
426  $sql .= " AND fk_statut <> 0";
427  $sql .= " AND entity = ".((int) $conf->entity);
428 
429  $resql = $this->db->query($sql);
430  if ($resql) {
431  $num = $this->db->num_rows($resql);
432  if ($num > 0) {
433  return 0;
434  }
435  }
436 
437  $sql = "UPDATE ".MAIN_DB_PREFIX."delivery SET";
438  $sql .= " ref='".$this->db->escape($numref)."'";
439  $sql .= ", fk_statut = 1";
440  $sql .= ", date_valid = '".$this->db->idate($now)."'";
441  $sql .= ", fk_user_valid = ".$user->id;
442  $sql .= " WHERE rowid = ".((int) $this->id);
443  $sql .= " AND fk_statut = 0";
444 
445  $resql = $this->db->query($sql);
446  if (!$resql) {
447  dol_print_error($this->db);
448  $this->error = $this->db->lasterror();
449  $error++;
450  }
451 
452  if (!$error && !$notrigger) {
453  // Call trigger
454  $result = $this->call_trigger('DELIVERY_VALIDATE', $user);
455  if ($result < 0) {
456  $error++;
457  }
458  // End call triggers
459  }
460 
461  if (!$error) {
462  $this->oldref = $this->ref;
463 
464  // Rename directory if dir was a temporary ref
465  if (preg_match('/^[\(]?PROV/i', $this->ref)) {
466  // Now we rename also files into index
467  $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)."'";
468  $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'expedition/receipt/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity);
469  $resql = $this->db->query($sql);
470  if (!$resql) {
471  $error++; $this->error = $this->db->lasterror();
472  }
473 
474  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
475  $oldref = dol_sanitizeFileName($this->ref);
476  $newref = dol_sanitizeFileName($numref);
477  $dirsource = $conf->expedition->dir_output.'/receipt/'.$oldref;
478  $dirdest = $conf->expedition->dir_output.'/receipt/'.$newref;
479  if (!$error && file_exists($dirsource)) {
480  dol_syslog(get_class($this)."::valid rename dir ".$dirsource." into ".$dirdest);
481 
482  if (@rename($dirsource, $dirdest)) {
483  dol_syslog("Rename ok");
484  // Rename docs starting with $oldref with $newref
485  $listoffiles = dol_dir_list($conf->expedition->dir_output.'/receipt/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
486  foreach ($listoffiles as $fileentry) {
487  $dirsource = $fileentry['name'];
488  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
489  $dirsource = $fileentry['path'].'/'.$dirsource;
490  $dirdest = $fileentry['path'].'/'.$dirdest;
491  @rename($dirsource, $dirdest);
492  }
493  }
494  }
495  }
496 
497  // Set new ref and current status
498  if (!$error) {
499  $this->ref = $numref;
500  $this->statut = 1;
501  }
502 
503  dol_syslog(get_class($this)."::valid ok");
504  }
505 
506  if (!$error) {
507  $this->db->commit();
508  return 1;
509  } else {
510  $this->db->rollback();
511  return -1;
512  }
513  }
514  }
515  } else {
516  $this->error = "Non autorise";
517  dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
518  return -1;
519  }
520  }
521 
522  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
530  public function create_from_sending($user, $sending_id)
531  {
532  // phpcs:enable
533  global $conf;
534 
535  $expedition = new Expedition($this->db);
536  $result = $expedition->fetch($sending_id);
537 
538  $this->lines = array();
539 
540  $num = count($expedition->lines);
541  for ($i = 0; $i < $num; $i++) {
542  $line = new DeliveryLine($this->db);
543  $line->origin_line_id = $expedition->lines[$i]->origin_line_id;
544  $line->label = $expedition->lines[$i]->label;
545  $line->description = $expedition->lines[$i]->description;
546  $line->qty = $expedition->lines[$i]->qty_shipped;
547  $line->fk_product = $expedition->lines[$i]->fk_product;
548  if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && is_array($expedition->lines[$i]->array_options) && count($expedition->lines[$i]->array_options) > 0) { // For avoid conflicts if trigger used
549  $line->array_options = $expedition->lines[$i]->array_options;
550  }
551  $this->lines[$i] = $line;
552  }
553 
554  $this->origin = $expedition->element;
555  $this->origin_id = $expedition->id;
556  $this->note_private = $expedition->note_private;
557  $this->note_public = $expedition->note_public;
558  $this->fk_project = $expedition->fk_project;
559  $this->date_delivery = $expedition->date_delivery;
560  $this->fk_delivery_address = $expedition->fk_delivery_address;
561  $this->socid = $expedition->socid;
562  $this->ref_customer = $expedition->ref_customer;
563 
564  //Incoterms
565  $this->fk_incoterms = $expedition->fk_incoterms;
566  $this->location_incoterms = $expedition->location_incoterms;
567 
568  return $this->create($user);
569  }
570 
571  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
579  public function update_line($id, $array_options = 0)
580  {
581  // phpcs:enable
582  global $conf;
583  $error = 0;
584 
585  if ($id > 0 && !$error && empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && is_array($array_options) && count($array_options) > 0) { // For avoid conflicts if trigger used
586  $line = new DeliveryLine($this->db);
587  $line->array_options = $array_options;
588  $line->id = $id;
589  $result = $line->insertExtraFields();
590 
591  if ($result < 0) {
592  $this->error[] = $line->error;
593  $error++;
594  }
595  }
596 
597  if (!$error) {
598  return 1;
599  } else {
600  return -1;
601  }
602  }
603 
604 
613  public function addline($origin_id, $qty, $array_options = null)
614  {
615  global $conf;
616 
617  $num = count($this->lines);
618  $line = new DeliveryLine($this->db);
619 
620  $line->origin_id = $origin_id;
621  $line->qty = $qty;
622  if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && is_array($array_options) && count($array_options) > 0) { // For avoid conflicts if trigger used
623  $line->array_options = $array_options;
624  }
625  $this->lines[$num] = $line;
626  }
627 
634  public function deleteline($lineid)
635  {
636  if ($this->statut == 0) {
637  $sql = "DELETE FROM ".MAIN_DB_PREFIX."commandedet";
638  $sql .= " WHERE rowid = ".((int) $lineid);
639 
640  if ($this->db->query($sql)) {
641  $this->update_price(1);
642 
643  return 1;
644  } else {
645  return 0;
646  }
647  }
648  }
649 
655  public function delete()
656  {
657  global $conf, $langs, $user;
658 
659  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
660  $this->db->begin();
661 
662  $error = 0;
663 
664  $sql = "DELETE FROM ".MAIN_DB_PREFIX."deliverydet";
665  $sql .= " WHERE fk_delivery = ".((int) $this->id);
666  if ($this->db->query($sql)) {
667  // Delete linked object
668  $res = $this->deleteObjectLinked();
669  if ($res < 0) {
670  $error++;
671  }
672 
673  if (!$error) {
674  $sql = "DELETE FROM ".MAIN_DB_PREFIX."delivery";
675  $sql .= " WHERE rowid = ".((int) $this->id);
676  if ($this->db->query($sql)) {
677  $this->db->commit();
678 
679  // Deleting pdf folder's draft On efface le repertoire de pdf provisoire
680  $ref = dol_sanitizeFileName($this->ref);
681  if (!empty($conf->expedition->dir_output)) {
682  $dir = $conf->expedition->dir_output.'/receipt/'.$ref;
683  $file = $dir.'/'.$ref.'.pdf';
684  if (file_exists($file)) {
685  if (!dol_delete_file($file)) {
686  return 0;
687  }
688  }
689  if (file_exists($dir)) {
690  if (!dol_delete_dir($dir)) {
691  $this->error = $langs->trans("ErrorCanNotDeleteDir", $dir);
692  return 0;
693  }
694  }
695  }
696 
697  // Call trigger
698  $result = $this->call_trigger('DELIVERY_DELETE', $user);
699  if ($result < 0) {
700  $this->db->rollback();
701  return -4;
702  }
703  // End call triggers
704 
705  return 1;
706  } else {
707  $this->error = $this->db->lasterror()." - sql=$sql";
708  $this->db->rollback();
709  return -3;
710  }
711  } else {
712  $this->error = $this->db->lasterror()." - sql=$sql";
713  $this->db->rollback();
714  return -2;
715  }
716  } else {
717  $this->error = $this->db->lasterror()." - sql=$sql";
718  $this->db->rollback();
719  return -1;
720  }
721  }
722 
730  public function getNomUrl($withpicto = 0, $save_lastsearch_value = -1)
731  {
732  global $langs, $hookmanager;
733 
734  $result = '';
735 
736  $label = img_picto('', $this->picto).' <u>'.$langs->trans("ShowReceiving").'</u>:<br>';
737  $label .= '<b>'.$langs->trans("Status").'</b>: '.$this->ref;
738 
739  $url = DOL_URL_ROOT.'/delivery/card.php?id='.$this->id;
740 
741  //if ($option !== 'nolink')
742  //{
743  // Add param to save lastsearch_values or not
744  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
745  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
746  $add_save_lastsearch_values = 1;
747  }
748  if ($add_save_lastsearch_values) {
749  $url .= '&save_lastsearch_values=1';
750  }
751  //}
752 
753 
754  $linkstart = '<a href="'.$url.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
755  $linkend = '</a>';
756 
757  if ($withpicto) {
758  $result .= ($linkstart.img_object($label, $this->picto, 'class="classfortooltip"').$linkend);
759  }
760  if ($withpicto && $withpicto != 2) {
761  $result .= ' ';
762  }
763  $result .= $linkstart.$this->ref.$linkend;
764 
765  global $action;
766  $hookmanager->initHooks(array($this->element . 'dao'));
767  $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
768  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
769  if ($reshook > 0) {
770  $result = $hookmanager->resPrint;
771  } else {
772  $result .= $hookmanager->resPrint;
773  }
774  return $result;
775  }
776 
777  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
783  public function fetch_lines()
784  {
785  // phpcs:enable
786  $this->lines = array();
787 
788  $sql = "SELECT ld.rowid, ld.fk_product, ld.description, ld.subprice, ld.total_ht, ld.qty as qty_shipped, ld.fk_origin_line, ";
789  $sql .= " cd.qty as qty_asked, cd.label as custom_label, cd.fk_unit,";
790  $sql .= " p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc,";
791  $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";
792  $sql .= " FROM ".MAIN_DB_PREFIX."commandedet as cd, ".MAIN_DB_PREFIX."deliverydet as ld";
793  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p on p.rowid = ld.fk_product";
794  $sql .= " WHERE ld.fk_origin_line = cd.rowid";
795  $sql .= " AND ld.fk_delivery = ".((int) $this->id);
796 
797  dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG);
798  $resql = $this->db->query($sql);
799  if ($resql) {
800  $num = $this->db->num_rows($resql);
801  $i = 0;
802  while ($i < $num) {
803  $obj = $this->db->fetch_object($resql);
804 
805  $line = new DeliveryLine($this->db);
806 
807  $line->id = $obj->rowid;
808  $line->label = $obj->custom_label;
809  $line->description = $obj->description;
810  $line->fk_product = $obj->fk_product;
811  $line->qty_asked = $obj->qty_asked;
812  $line->qty_shipped = $obj->qty_shipped;
813 
814  $line->ref = $obj->product_ref; // deprecated
815  $line->libelle = $obj->product_label; // deprecated
816  $line->product_label = $obj->product_label; // Product label
817  $line->product_ref = $obj->product_ref; // Product ref
818  $line->product_desc = $obj->product_desc; // Product description
819  $line->product_type = $obj->fk_product_type;
820  $line->fk_origin_line = $obj->fk_origin_line;
821 
822  $line->price = $obj->subprice;
823  $line->total_ht = $obj->total_ht;
824 
825  // units
826  $line->weight = $obj->weight;
827  $line->weight_units = $obj->weight_units;
828  $line->width = $obj->width;
829  $line->width_units = $obj->width_units;
830  $line->height = $obj->height;
831  $line->height_units = $obj->height_units;
832  $line->length = $obj->length;
833  $line->length_units = $obj->length_units;
834  $line->surface = $obj->surface;
835  $line->surface_units = $obj->surface_units;
836  $line->volume = $obj->volume;
837  $line->volume_units = $obj->volume_units;
838 
839  $line->fk_unit = $obj->fk_unit;
840  $line->fetch_optionals();
841 
842  $this->lines[$i] = $line;
843 
844  $i++;
845  }
846  $this->db->free($resql);
847 
848  return 1;
849  } else {
850  return -1;
851  }
852  }
853 
854 
861  public function getLibStatut($mode = 0)
862  {
863  return $this->LibStatut($this->statut, $mode);
864  }
865 
866  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
874  public function LibStatut($status, $mode)
875  {
876  // phpcs:enable
877  global $langs;
878 
879  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
880  global $langs;
881  //$langs->load("mymodule");
882  $this->labelStatus[-1] = $langs->transnoentitiesnoconv('StatusDeliveryCanceled');
883  $this->labelStatus[0] = $langs->transnoentitiesnoconv('StatusDeliveryDraft');
884  $this->labelStatus[1] = $langs->transnoentitiesnoconv('StatusDeliveryValidated');
885  $this->labelStatusShort[-1] = $langs->transnoentitiesnoconv('StatusDeliveryCanceled');
886  $this->labelStatusShort[0] = $langs->transnoentitiesnoconv('StatusDeliveryDraft');
887  $this->labelStatusShort[1] = $langs->transnoentitiesnoconv('StatusDeliveryValidated');
888  }
889 
890  $statusType = 'status0';
891  if ($status == -1) {
892  $statusType = 'status5';
893  }
894  if ($status == 1) {
895  $statusType = 'status4';
896  }
897 
898  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
899  }
900 
901 
909  public function initAsSpecimen()
910  {
911  global $user, $langs, $conf;
912 
913  $now = dol_now();
914 
915  // Load array of products prodids
916  $num_prods = 0;
917  $prodids = array();
918  $sql = "SELECT rowid";
919  $sql .= " FROM ".MAIN_DB_PREFIX."product";
920  $sql .= " WHERE entity IN (".getEntity('product').")";
921  $sql .= " AND tosell = 1";
922  $sql .= $this->db->plimit(100);
923 
924  $resql = $this->db->query($sql);
925  if ($resql) {
926  $num_prods = $this->db->num_rows($resql);
927  $i = 0;
928  while ($i < $num_prods) {
929  $i++;
930  $row = $this->db->fetch_row($resql);
931  $prodids[$i] = $row[0];
932  }
933  }
934 
935  // Initialise parametres
936  $this->id = 0;
937  $this->ref = 'SPECIMEN';
938  $this->specimen = 1;
939  $this->socid = 1;
940  $this->date_delivery = $now;
941  $this->note_public = 'Public note';
942  $this->note_private = 'Private note';
943 
944  $i = 0;
945  $line = new DeliveryLine($this->db);
946  $line->fk_product = $prodids[0];
947  $line->qty_asked = 10;
948  $line->qty_shipped = 9;
949  $line->ref = 'REFPROD';
950  $line->label = 'Specimen';
951  $line->description = 'Description';
952  $line->price = 100;
953  $line->total_ht = 100;
954 
955  $this->lines[$i] = $line;
956  }
957 
964  public function getRemainingDelivered()
965  {
966  global $langs;
967 
968  // Get the linked object
969  $this->fetchObjectLinked('', '', $this->id, $this->element);
970  //var_dump($this->linkedObjectsIds);
971  // Get the product ref and qty in source
972  $sqlSourceLine = "SELECT st.rowid, st.description, st.qty";
973  $sqlSourceLine .= ", p.ref, p.label";
974  $sqlSourceLine .= " FROM ".MAIN_DB_PREFIX.$this->linkedObjectsIds[0]['type']."det as st";
975  $sqlSourceLine .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON st.fk_product = p.rowid";
976  $sqlSourceLine .= " WHERE fk_".$this->linked_objects[0]['type']." = ".((int) $this->linked_objects[0]['linkid']);
977 
978  $resultSourceLine = $this->db->query($sqlSourceLine);
979  if ($resultSourceLine) {
980  $num_lines = $this->db->num_rows($resultSourceLine);
981  $i = 0;
982  $array = array();
983  while ($i < $num_lines) {
984  $objSourceLine = $this->db->fetch_object($resultSourceLine);
985 
986  // Get lines of sources alread delivered
987  $sql = "SELECT ld.fk_origin_line, sum(ld.qty) as qty";
988  $sql .= " FROM ".MAIN_DB_PREFIX."deliverydet as ld, ".MAIN_DB_PREFIX."delivery as l,";
989  $sql .= " ".MAIN_DB_PREFIX.$this->linked_objects[0]['type']." as c";
990  $sql .= ", ".MAIN_DB_PREFIX.$this->linked_objects[0]['type']."det as cd";
991  $sql .= " WHERE ld.fk_delivery = l.rowid";
992  $sql .= " AND ld.fk_origin_line = cd.rowid";
993  $sql .= " AND cd.fk_".$this->linked_objects[0]['type']." = c.rowid";
994  $sql .= " AND cd.fk_".$this->linked_objects[0]['type']." = ".((int) $this->linked_objects[0]['linkid']);
995  $sql .= " AND ld.fk_origin_line = ".((int) $objSourceLine->rowid);
996  $sql .= " GROUP BY ld.fk_origin_line";
997 
998  $result = $this->db->query($sql);
999  $row = $this->db->fetch_row($result);
1000 
1001  if ($objSourceLine->qty - $row[1] > 0) {
1002  if ($row[0] == $objSourceLine->rowid) {
1003  $array[$i]['qty'] = $objSourceLine->qty - $row[1];
1004  } else {
1005  $array[$i]['qty'] = $objSourceLine->qty;
1006  }
1007 
1008  $array[$i]['ref'] = $objSourceLine->ref;
1009  $array[$i]['label'] = $objSourceLine->label ? $objSourceLine->label : $objSourceLine->description;
1010  } elseif ($objSourceLine->qty - $row[1] < 0) {
1011  $array[$i]['qty'] = $objSourceLine->qty - $row[1]." Erreur livraison !";
1012  $array[$i]['ref'] = $objSourceLine->ref;
1013  $array[$i]['label'] = $objSourceLine->label ? $objSourceLine->label : $objSourceLine->description;
1014  }
1015 
1016  $i++;
1017  }
1018  return $array;
1019  } else {
1020  $this->error = $this->db->error()." - sql=$sqlSourceLine";
1021  return -1;
1022  }
1023  }
1024 
1032  public function setDeliveryDate($user, $delivery_date)
1033  {
1034  if ($user->rights->expedition->creer) {
1035  $sql = "UPDATE ".MAIN_DB_PREFIX."delivery";
1036  $sql .= " SET date_delivery = ".($delivery_date ? "'".$this->db->idate($delivery_date)."'" : 'null');
1037  $sql .= " WHERE rowid = ".((int) $this->id);
1038 
1039  dol_syslog(get_class($this)."::setDeliveryDate", LOG_DEBUG);
1040  $resql = $this->db->query($sql);
1041  if ($resql) {
1042  $this->date_delivery = $delivery_date;
1043  return 1;
1044  } else {
1045  $this->error = $this->db->error();
1046  return -1;
1047  }
1048  } else {
1049  return -2;
1050  }
1051  }
1052 
1063  public function generateDocument($modele, $outputlangs = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
1064  {
1065  global $conf, $user, $langs;
1066 
1067  $langs->load("deliveries");
1068  $outputlangs->load("products");
1069 
1070  if (!dol_strlen($modele)) {
1071  $modele = 'typhon';
1072 
1073  if ($this->model_pdf) {
1074  $modele = $this->model_pdf;
1075  } elseif (!empty($conf->global->DELIVERY_ADDON_PDF)) {
1076  $modele = $conf->global->DELIVERY_ADDON_PDF;
1077  }
1078  }
1079 
1080  $modelpath = "core/modules/delivery/doc/";
1081 
1082  return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
1083  }
1084 
1093  public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
1094  {
1095  $tables = array(
1096  'delivery'
1097  );
1098 
1099  return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
1100  }
1101 
1110  public static function replaceProduct(DoliDB $db, $origin_id, $dest_id)
1111  {
1112  $tables = array(
1113  'deliverydet'
1114  );
1115 
1116  return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables);
1117  }
1118 }
1119 
1120 
1121 
1126 {
1130  public $db;
1131 
1135  public $element = 'deliverydet';
1136 
1140  public $table_element = 'deliverydet';
1141 
1145  public $label;
1146 
1150  public $description;
1151 
1156  public $ref;
1161  public $libelle;
1162 
1163  // From llx_expeditiondet
1164  public $qty;
1165  public $qty_asked;
1166  public $qty_shipped;
1167 
1168  public $fk_product;
1169  public $product_desc;
1170  public $product_type;
1171  public $product_ref;
1172  public $product_label;
1173 
1174  public $fk_origin_line;
1175  public $origin_id;
1176 
1177  public $price;
1178 
1179  public $origin_line_id;
1180 
1181 
1187  public function __construct($db)
1188  {
1189  $this->db = $db;
1190  }
1191 }
Delivery\initAsSpecimen
initAsSpecimen()
Initialise an instance with random values.
Definition: delivery.class.php:909
Societe
Class to manage third parties objects (customers, suppliers, prospects...)
Definition: societe.class.php:49
db
$conf db
API class for accounts.
Definition: inc.php:41
dol_escape_htmltag
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields.
Definition: functions.lib.php:1493
Delivery\create_line
create_line($origin_id, $qty, $fk_product, $description, $array_options=null)
Create a line.
Definition: delivery.class.php:270
dol_sanitizeFileName
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
Definition: functions.lib.php:1225
description
print *****$script_file(".$version.") pid cd cd cd description as description
Definition: email_expire_services_to_customers.php:83
Expedition
Class to manage shipments.
Definition: expedition.class.php:52
Delivery\__construct
__construct($db)
Constructor.
Definition: delivery.class.php:119
DoliDB
Class to manage Dolibarr database access.
Definition: DoliDB.class.php:30
CommonObject\fetchObjectLinked
fetchObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $clause='OR', $alsosametype=1, $orderby='sourcetype', $loadalsoobjects=1)
Fetch array of objects linked to current object (object of enabled modules only).
Definition: commonobject.class.php:3932
dol_print_error
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
Definition: functions.lib.php:4993
Delivery\getNomUrl
getNomUrl($withpicto=0, $save_lastsearch_value=-1)
Return clicable name (with picto eventually)
Definition: delivery.class.php:730
ref
$object ref
Definition: info.php:78
Delivery\valid
valid($user, $notrigger=0)
Validate object and update stock if option enabled.
Definition: delivery.class.php:388
dol_dir_list
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition: files.lib.php:61
CommonIncoterm
trait CommonIncoterm
Superclass for incoterm classes.
Definition: commonincoterm.class.php:29
CommonObject\deleteObjectLinked
deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid='', $f_user=null, $notrigger=0)
Delete all links between an object $this.
Definition: commonobject.class.php:4244
CommonObject\commonReplaceProduct
static commonReplaceProduct(DoliDB $db, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a product id with another one.
Definition: commonobject.class.php:8528
Delivery\create
create($user)
Create delivery receipt in database.
Definition: delivery.class.php:135
CommonObject\setStatut
setStatut($status, $elementId=null, $elementType='', $trigkey='', $fieldstatus='fk_statut')
Set status of an object.
Definition: commonobject.class.php:4380
Delivery\fetch_lines
fetch_lines()
Load lines insto $this->lines.
Definition: delivery.class.php:783
CommonObjectLine
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Definition: commonobjectline.class.php:32
CommonObject
Parent class of all other business classes (invoices, contracts, proposals, orders,...
Definition: commonobject.class.php:44
price2num
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
Definition: functions.lib.php:5823
Delivery\getLibStatut
getLibStatut($mode=0)
Retourne le libelle du statut d'une expedition.
Definition: delivery.class.php:861
Delivery\generateDocument
generateDocument($modele, $outputlangs='', $hidedetails=0, $hidedesc=0, $hideref=0)
Create object on disk.
Definition: delivery.class.php:1063
DeliveryLine\$libelle
$libelle
Definition: delivery.class.php:1161
Delivery\replaceProduct
static replaceProduct(DoliDB $db, $origin_id, $dest_id)
Function used to replace a product id with another one.
Definition: delivery.class.php:1110
img_picto
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
Definition: functions.lib.php:4024
CommonObject\commonGenerateDocument
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
Definition: commonobject.class.php:5427
dol_delete_file
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
Definition: files.lib.php:1251
Delivery\LibStatut
LibStatut($status, $mode)
Renvoi le libelle d'un statut donne.
Definition: delivery.class.php:874
CommonObject\update_price
update_price($exclspec=0, $roundingadjust='none', $nodatabaseupdate=0, $seller=null)
Update total_ht, total_ttc, total_vat, total_localtax1, total_localtax2 for an object (sum of lines).
Definition: commonobject.class.php:3550
Delivery\fetch
fetch($id)
Load a delivery receipt.
Definition: delivery.class.php:309
Delivery\replaceThirdparty
static replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
Definition: delivery.class.php:1093
DeliveryLine\$ref
$ref
Definition: delivery.class.php:1156
$resql
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:745
Commande
Class to manage customers orders.
Definition: commande.class.php:46
dol_delete_dir
dol_delete_dir($dir, $nophperrors=0)
Remove a directory (not recursive, so content must be empty).
Definition: files.lib.php:1377
Delivery\update_line
update_line($id, $array_options=0)
Update a livraison line (only extrafields)
Definition: delivery.class.php:579
CommonObject\commonReplaceThirdparty
static commonReplaceThirdparty(DoliDB $db, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
Definition: commonobject.class.php:8499
dol_syslog
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
Definition: functions.lib.php:1628
Delivery\addline
addline($origin_id, $qty, $array_options=null)
Add line.
Definition: delivery.class.php:613
CommonObject\fetch_optionals
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
Definition: commonobject.class.php:6034
dol_strlen
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
Definition: functions.lib.php:3887
isModEnabled
isModEnabled($module)
Is Dolibarr module enabled.
Definition: functions.lib.php:137
Delivery\deleteline
deleteline($lineid)
Delete line.
Definition: delivery.class.php:634
Delivery\getRemainingDelivered
getRemainingDelivered()
Renvoie la quantite de produit restante a livrer pour une commande.
Definition: delivery.class.php:964
DeliveryLine
Management class of delivery note lines.
Definition: delivery.class.php:1125
Delivery\create_from_sending
create_from_sending($user, $sending_id)
Creating the delivery slip from an existing shipment.
Definition: delivery.class.php:530
Delivery\setDeliveryDate
setDeliveryDate($user, $delivery_date)
Set the planned delivery date.
Definition: delivery.class.php:1032
CommonObject\add_object_linked
add_object_linked($origin=null, $origin_id=null, $f_user=null, $notrigger=0)
Add an object link into llx_element_element.
Definition: commonobject.class.php:3834
dolGetStatus
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
Definition: functions.lib.php:10745
dol_now
dol_now($mode='auto')
Return date for now.
Definition: functions.lib.php:2951
DeliveryLine\__construct
__construct($db)
Constructor.
Definition: delivery.class.php:1187
Delivery
Class to manage receptions.
Definition: delivery.class.php:45
CommonObject\call_trigger
call_trigger($triggerName, $user)
Call trigger based on this instance.
Definition: commonobject.class.php:5818
user
$conf db user
Definition: repair.php:123