dolibarr  9.0.0
entrepot.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2003-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2010 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005-2008 Regis Houssin <regis.houssin@inodbox.com>
5  * Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es>
6  * Copyright (C) 2016 Francis Appels <francis.appels@yahoo.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
28 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
29 
30 
34 class Entrepot extends CommonObject
35 {
39  public $element='stock';
40 
44  public $table_element='entrepot';
45 
46  public $picto='stock';
47 
51  const STATUS_CLOSED = 0;
52 
56  const STATUS_OPEN_ALL = 1;
57 
62 
63  public $libelle;
64 
68  public $description;
69 
70  public $statut;
71  public $lieu;
72 
76  public $address;
77 
79  public $zip;
80  public $town;
81 
85  public $fk_parent;
86 
87  // List of short language codes for status
88  public $statuts = array();
89 
95  function __construct($db)
96  {
97  global $conf;
98  $this->db = $db;
99 
100  $this->statuts[self::STATUS_CLOSED] = 'Closed2';
101  if ($conf->global->ENTREPOT_EXTRA_STATUS)
102  {
103  $this->statuts[self::STATUS_OPEN_ALL] = 'OpenAll';
104  $this->statuts[self::STATUS_OPEN_INTERNAL] = 'OpenInternal';
105  }
106  else
107  {
108  $this->statuts[self::STATUS_OPEN_ALL] = 'Opened';
109  }
110  }
111 
118  function create($user)
119  {
120  global $conf;
121 
122  $error = 0;
123 
124  $this->libelle = trim($this->libelle);
125 
126  // Si libelle non defini, erreur
127  if ($this->libelle == '')
128  {
129  $this->error = "ErrorFieldRequired";
130  return 0;
131  }
132 
133  $now=dol_now();
134 
135  $this->db->begin();
136 
137  $sql = "INSERT INTO ".MAIN_DB_PREFIX."entrepot (ref, entity, datec, fk_user_author, fk_parent)";
138  $sql .= " VALUES ('".$this->db->escape($this->libelle)."', ".$conf->entity.", '".$this->db->idate($now)."', ".$user->id.", ".($this->fk_parent > 0 ? $this->fk_parent : "NULL").")";
139 
140  dol_syslog(get_class($this)."::create", LOG_DEBUG);
141  $result=$this->db->query($sql);
142  if ($result)
143  {
144  $id = $this->db->last_insert_id(MAIN_DB_PREFIX."entrepot");
145  if ($id > 0)
146  {
147  $this->id = $id;
148 
149  if (! $error)
150  {
151  $result = $this->update($id, $user);
152  if ($result <= 0)
153  {
154  $error++;
155  }
156  }
157 
158  if (! $error)
159  {
160  $this->db->commit();
161  return $id;
162  }
163  else
164  {
165  dol_syslog(get_class($this)."::create return -3");
166  $this->db->rollback();
167  return -3;
168  }
169  }
170  else {
171  $this->error="Failed to get insert id";
172  dol_syslog(get_class($this)."::create return -2");
173  return -2;
174  }
175  }
176  else
177  {
178  $this->error=$this->db->error();
179  dol_syslog(get_class($this)."::create Error ".$this->db->error());
180  $this->db->rollback();
181  return -1;
182  }
183  }
184 
192  function update($id, $user)
193  {
194  if (empty($id)) $id = $this->id;
195 
196  // Check if new parent is already a child of current warehouse
197  if(!empty($this->fk_parent))
198  {
199  $TChildWarehouses = array($id);
200  $TChildWarehouses = $this->get_children_warehouses($this->id, $TChildWarehouses);
201  if(in_array($this->fk_parent, $TChildWarehouses))
202  {
203  $this->error = 'ErrorCannotAddThisParentWarehouse';
204  return -2;
205  }
206  }
207 
208  $this->libelle=trim($this->libelle);
209  $this->description=trim($this->description);
210 
211  $this->lieu=trim($this->lieu);
212 
213  $this->address=trim($this->address);
214  $this->zip=trim($this->zip);
215  $this->town=trim($this->town);
216  $this->country_id=($this->country_id > 0 ? $this->country_id : 0);
217 
218  $sql = "UPDATE ".MAIN_DB_PREFIX."entrepot ";
219  $sql .= " SET ref = '" . $this->db->escape($this->libelle) ."'";
220  $sql .= ", fk_parent = " . (($this->fk_parent > 0) ? $this->fk_parent : "NULL");
221  $sql .= ", description = '" . $this->db->escape($this->description) ."'";
222  $sql .= ", statut = " . $this->statut;
223  $sql .= ", lieu = '" . $this->db->escape($this->lieu) ."'";
224  $sql .= ", address = '" . $this->db->escape($this->address) ."'";
225  $sql .= ", zip = '" . $this->db->escape($this->zip) ."'";
226  $sql .= ", town = '" . $this->db->escape($this->town) ."'";
227  $sql .= ", fk_pays = " . $this->country_id;
228  $sql .= " WHERE rowid = " . $id;
229 
230  $this->db->begin();
231 
232  dol_syslog(get_class($this)."::update", LOG_DEBUG);
233  $resql=$this->db->query($sql);
234  if ($resql)
235  {
236  $this->db->commit();
237  return 1;
238  }
239  else
240  {
241  $this->db->rollback();
242  $this->error=$this->db->lasterror();
243  return -1;
244  }
245  }
246 
247 
255  function delete($user, $notrigger=0)
256  {
257  $this->db->begin();
258 
259  if (! $error && empty($notrigger))
260  {
261  // Call trigger
262  $result=$this->call_trigger('WAREHOUSE_DELETE',$user);
263  if ($result < 0) { $error++; }
264  // End call triggers
265  }
266 
267  $elements = array('stock_mouvement','product_stock','product_warehouse_properties');
268  foreach($elements as $table)
269  {
270  if (! $error)
271  {
272  $sql = "DELETE FROM ".MAIN_DB_PREFIX.$table;
273  $sql.= " WHERE fk_entrepot = " . $this->id;
274  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
275  $result=$this->db->query($sql);
276  if (! $result)
277  {
278  $error++;
279  $this->errors[] = $this->db->lasterror();
280  }
281  }
282  }
283 
284  if (! $error)
285  {
286  $sql = "DELETE FROM ".MAIN_DB_PREFIX."entrepot";
287  $sql.= " WHERE rowid = " . $this->id;
288 
289  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
290  $resql1=$this->db->query($sql);
291 
292  // Update denormalized fields because we change content of produt_stock. Warning: Do not use "SET p.stock", does not works with pgsql
293  $sql = "UPDATE ".MAIN_DB_PREFIX."product as p SET stock = (SELECT SUM(ps.reel) FROM ".MAIN_DB_PREFIX."product_stock as ps WHERE ps.fk_product = p.rowid)";
294 
295  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
296  $resql2=$this->db->query($sql);
297 
298  if ($resql1 && $resql2)
299  {
300  $this->db->commit();
301  return 1;
302  }
303  else
304  {
305  $this->db->rollback();
306  $this->error=$this->db->lasterror();
307  return -2;
308  }
309  }
310  else
311  {
312  $this->db->rollback();
313  $this->error=$this->db->lasterror();
314  return -1;
315  }
316  }
317 
318 
326  function fetch($id, $ref='')
327  {
328  global $conf;
329 
330  $sql = "SELECT rowid, fk_parent, ref as label, description, statut, lieu, address, zip, town, fk_pays as country_id";
331  $sql .= " FROM ".MAIN_DB_PREFIX."entrepot";
332  if ($id)
333  {
334  $sql.= " WHERE rowid = '".$id."'";
335  }
336  else
337  {
338  $sql.= " WHERE entity = " .$conf->entity;
339  if ($ref) $sql.= " AND ref = '".$this->db->escape($ref)."'";
340  }
341 
342  dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
343  $result = $this->db->query($sql);
344  if ($result)
345  {
346  if ($this->db->num_rows($result) > 0)
347  {
348  $obj=$this->db->fetch_object($result);
349 
350  $this->id = $obj->rowid;
351  $this->fk_parent = $obj->fk_parent;
352  $this->ref = $obj->label;
353  $this->label = $obj->label; // deprecated
354  $this->libelle = $obj->label; // deprecated
355  $this->description = $obj->description;
356  $this->statut = $obj->statut;
357  $this->lieu = $obj->lieu;
358  $this->address = $obj->address;
359  $this->zip = $obj->zip;
360  $this->town = $obj->town;
361  $this->country_id = $obj->country_id;
362 
363  include_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
364  $tmp=getCountry($this->country_id,'all');
365  $this->country=$tmp['label'];
366  $this->country_code=$tmp['code'];
367 
368  return 1;
369  }
370  else
371  {
372  return 0;
373  }
374  }
375  else
376  {
377  $this->error=$this->db->error();
378  return -1;
379  }
380  }
381 
382 
389  function info($id)
390  {
391  $sql = "SELECT e.rowid, e.datec, e.tms as datem, e.fk_user_author";
392  $sql.= " FROM ".MAIN_DB_PREFIX."entrepot as e";
393  $sql.= " WHERE e.rowid = ".$id;
394 
395  dol_syslog(get_class($this)."::info", LOG_DEBUG);
396  $result=$this->db->query($sql);
397  if ($result)
398  {
399  if ($this->db->num_rows($result))
400  {
401  $obj = $this->db->fetch_object($result);
402 
403  $this->id = $obj->rowid;
404 
405  if ($obj->fk_user_author) {
406  $cuser = new User($this->db);
407  $cuser->fetch($obj->fk_user_author);
408  $this->user_creation = $cuser;
409  }
410 
411  if ($obj->fk_user_valid) {
412  $vuser = new User($this->db);
413  $vuser->fetch($obj->fk_user_valid);
414  $this->user_validation = $vuser;
415  }
416 
417  $this->date_creation = $this->db->jdate($obj->datec);
418  $this->date_modification = $this->db->jdate($obj->datem);
419  }
420 
421  $this->db->free($result);
422  }
423  else
424  {
425  dol_print_error($this->db);
426  }
427  }
428 
429 
430  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
437  function list_array($status=1)
438  {
439  // phpcs:enable
440  $liste = array();
441 
442  $sql = "SELECT rowid, ref as label";
443  $sql.= " FROM ".MAIN_DB_PREFIX."entrepot";
444  $sql.= " WHERE entity IN (".getEntity('stock').")";
445  $sql.= " AND statut = ".$status;
446 
447  $result = $this->db->query($sql);
448  $i = 0;
449  $num = $this->db->num_rows($result);
450  if ( $result )
451  {
452  while ($i < $num)
453  {
454  $row = $this->db->fetch_row($result);
455  $liste[$row[0]] = $row[1];
456  $i++;
457  }
458  $this->db->free($result);
459  }
460  return $liste;
461  }
462 
463  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
470  {
471  // phpcs:enable
472  $ret=array();
473 
474  $sql = "SELECT count(distinct p.rowid) as nb";
475  $sql.= " FROM ".MAIN_DB_PREFIX."product_stock as ps";
476  $sql.= ", ".MAIN_DB_PREFIX."product as p";
477  $sql.= " WHERE ps.fk_entrepot = ".$this->id;
478  $sql.= " AND ps.fk_product = p.rowid";
479 
480  //print $sql;
481  $result = $this->db->query($sql);
482  if ($result)
483  {
484  $obj = $this->db->fetch_object($result);
485  $ret['nb']=$obj->nb;
486  $this->db->free($result);
487  }
488  else
489  {
490  $this->error=$this->db->lasterror();
491  return -1;
492  }
493 
494  return $ret;
495  }
496 
497  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
503  function nb_products()
504  {
505  // phpcs:enable
506  $ret=array();
507 
508  $sql = "SELECT sum(ps.reel) as nb, sum(ps.reel * p.pmp) as value";
509  $sql.= " FROM ".MAIN_DB_PREFIX."product_stock as ps";
510  $sql.= ", ".MAIN_DB_PREFIX."product as p";
511  $sql.= " WHERE ps.fk_entrepot = ".$this->id;
512  $sql.= " AND ps.fk_product = p.rowid";
513 
514  //print $sql;
515  $result = $this->db->query($sql);
516  if ($result)
517  {
518  $obj = $this->db->fetch_object($result);
519  $ret['nb']=$obj->nb;
520  $ret['value']=$obj->value;
521  $this->db->free($result);
522  }
523  else
524  {
525  $this->error=$this->db->lasterror();
526  return -1;
527  }
528 
529  return $ret;
530  }
531 
538  function getLibStatut($mode=0)
539  {
540  return $this->LibStatut($this->statut,$mode);
541  }
542 
543  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
551  function LibStatut($statut,$mode=0)
552  {
553  // phpcs:enable
554  global $langs;
555 
556  $langs->load('stocks');
557 
558  $picto = 'statut5';
559  $label = $langs->trans($this->statuts[$statut]);
560 
561 
562  if ($mode == 0)
563  {
564  return $label;
565  }
566  if ($mode == 1)
567  {
568  return $label;
569  }
570  if ($mode == 2)
571  {
572  if ($statut > 0) $picto = 'statut4';
573  return img_picto($label, $picto).' '.$label;
574  }
575  if ($mode == 3)
576  {
577  if ($statut > 0) $picto = 'statut4';
578  return img_picto($label, $picto).' '.$label;
579  }
580  if ($mode == 4)
581  {
582  if ($statut > 0) $picto = 'statut4';
583  return img_picto($label, $picto).' '.$label;
584  }
585  if ($mode == 5)
586  {
587  if ($statut > 0) $picto = 'statut4';
588  return $label.' '.img_picto($label, $picto);
589  }
590  }
591 
592 
602  function getNomUrl($withpicto=0, $option='',$showfullpath=0, $notooltip=0)
603  {
604  global $conf, $langs;
605  $langs->load("stocks");
606 
607  if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips
608 
609  $result='';
610  $label = '';
611 
612  $label = '<u>' . $langs->trans("ShowWarehouse").'</u>';
613  $label.= '<br><b>' . $langs->trans('Ref') . ':</b> ' . (empty($this->ref)?(empty($this->label)?$this->libelle:$this->label):$this->ref);
614  if (! empty($this->lieu))
615  $label.= '<br><b>' . $langs->trans('LocationSummary').':</b> '.$this->lieu;
616 
617  $url = DOL_URL_ROOT.'/product/stock/card.php?id='.$this->id;
618 
619  $linkclose='';
620  if (empty($notooltip))
621  {
622  if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
623  {
624  $label=$langs->trans("ShowWarehouse");
625  $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"';
626  }
627  $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"';
628  $linkclose.=' class="classfortooltip"';
629  }
630 
631  $linkstart = '<a href="'.$url.'"';
632  $linkstart.=$linkclose.'>';
633  $linkend='</a>';
634 
635  $result .= $linkstart;
636  if ($withpicto) $result.=img_object(($notooltip?'':$label), ($this->picto?$this->picto:'generic'), ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1);
637  if ($withpicto != 2) $result.= ($showfullpath ? $this->get_full_arbo() : (empty($this->label)?$this->libelle:$this->label));
638  $result .= $linkend;
639 
640  return $result;
641  }
642 
650  function initAsSpecimen()
651  {
652  global $user,$langs,$conf,$mysoc;
653 
654  $now=dol_now();
655 
656  // Initialize parameters
657  $this->id=0;
658  $this->libelle = 'WAREHOUSE SPECIMEN';
659  $this->description = 'WAREHOUSE SPECIMEN '.dol_print_date($now,'dayhourlog');
660  $this->statut=1;
661  $this->specimen=1;
662 
663  $this->lieu='Location test';
664  $this->address='21 jump street';
665  $this->zip='99999';
666  $this->town='MyTown';
667  $this->country_id=1;
668  $this->country_code='FR';
669  }
670 
671  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
677  function get_full_arbo()
678  {
679  // phpcs:enable
680  global $user,$langs,$conf;
681 
682  $TArbo = array(empty($this->label)?$this->libelle:$this->label);
683 
684  $protection=100; // We limit depth of warehouses to 100
685 
686  $warehousetmp = new Entrepot($this->db);
687 
688  $parentid = $this->fk_parent; // If parent_id not defined on current object, we do not start consecutive searches of parents
689  $i=0;
690  while ($parentid > 0 && $i < $protection)
691  {
692  $sql = 'SELECT fk_parent FROM '.MAIN_DB_PREFIX.'entrepot WHERE rowid = '.$parentid;
693  $resql = $this->db->query($sql);
694  if ($resql)
695  {
696  $objarbo = $this->db->fetch_object($resql);
697  if ($objarbo)
698  {
699  $warehousetmp->fetch($parentid);
700  $TArbo[] = $warehousetmp->label;
701  $parentid = $objarbo->fk_parent;
702  }
703  else break;
704  }
705  else dol_print_error($this->db);
706 
707  $i++;
708  }
709 
710  return implode(' >> ', array_reverse($TArbo));
711  }
712 
713  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
721  function get_children_warehouses($id, &$TChildWarehouses)
722  {
723  // phpcs:enable
724 
725  $sql = 'SELECT rowid
726  FROM '.MAIN_DB_PREFIX.'entrepot
727  WHERE fk_parent = '.$id;
728 
729  $resql = $this->db->query($sql);
730  if($resql) {
731  while($res = $this->db->fetch_object($resql)) {
732  $TChildWarehouses[] = $res->rowid;
733  $this->get_children_warehouses($res->rowid, $TChildWarehouses);
734  }
735  }
736 
737  return $TChildWarehouses;
738  }
739 
750  public function generateDocument($modele, $outputlangs='',$hidedetails=0,$hidedesc=0,$hideref=0)
751  {
752  global $conf,$user,$langs;
753 
754  $langs->load("stocks");
755 
756  if (! dol_strlen($modele)) {
757 
758  $modele = 'standard';
759 
760  if ($this->modelpdf) {
761  $modele = $this->modelpdf;
762  } elseif (! empty($conf->global->STOCK_ADDON_PDF)) {
763  $modele = $conf->global->STOCK_ADDON_PDF;
764  }
765  }
766 
767  $modelpath = "core/modules/stock/doc/";
768 
769  return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
770  }
771 }
print $object label
hash of file content (md5_file(dol_osencode($destfull))
Definition: edit.php:153
const STATUS_CLOSED
Warehouse closed, inactive.
fetch($id, $ref='')
Load warehouse data.
if(! empty($conf->facture->enabled) && $user->rights->facture->lire) if(! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->lire) if(! empty($conf->don->enabled) && $user->rights->societe->lire) if(! empty($conf->tax->enabled) && $user->rights->tax->charges->lire) if(! empty($conf->facture->enabled) &&! empty($conf->commande->enabled) && $user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(! empty($conf->facture->enabled) && $user->rights->facture->lire) if(! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1053
nb_products()
Return stock and value of warehosue.
const STATUS_OPEN_ALL
Warehouse open and operations for customer shipping, supplier dispatch, internal stock transfers/corr...
</td >< td class="liste_titre" align="right"></td ></tr >< tr class="liste_titre">< input type="checkbox" onClick="toggle(this)"/> Ref p ref Label p label Duration p duration warehouseinternal SELECT description FROM product_lang WHERE qty< br > qty qty qty StockTooLow img yes disabled img no img no< tr class="oddeven">< td >< input type="checkbox" class="check" name="' . $i . '"' . $disabled . '></td >< td >< input type="checkbox" class="check" name="choose'.$i.'"></td >< td class="nowrap"></td >< td >< input type="hidden" name="desc' . $i . '" value="' . dol_escape_htmltag($objp-> description
Only used if Module[ID]Desc translation string is not found.
Definition: replenish.php:573
getLibStatut($mode=0)
Return label of status of object.
get_children_warehouses($id, &$TChildWarehouses)
Return array of children warehouses ids from $id warehouse (recursive function)
Class to manage Dolibarr users.
Definition: user.class.php:41
get_full_arbo()
Return full path to current warehouse.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
dol_print_error($db='', $error='', $errors=null)
Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte...
getCountry($searchkey, $withcode='', $dbtouse=0, $outputlangs='', $entconv=1, $searchlabel='')
Return country label, code or id from an id, code or label.
initAsSpecimen()
Initialise an instance with random values.
LibStatut($statut, $mode=0)
Return label of a given status.
info($id)
Load warehouse info data.
__construct($db)
Constructor.
const STATUS_OPEN_INTERNAL
Warehouse open and operations for stock transfers/corrections allowed (not for customer shipping and ...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='')
Write log message into outputs.
generateDocument($modele, $outputlangs='', $hidedetails=0, $hidedesc=0, $hideref=0)
Create object on disk.
dol_now($mode='gmt')
Return date for now.
list_array($status=1)
Return list of all warehouses.
$zip
Code Postal.
nb_different_products()
Return number of unique different product into a warehouse.
call_trigger($trigger_name, $user)
Call trigger based on this instance.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='')
Show picto whatever it&#39;s its name (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
getNomUrl($withpicto=0, $option='', $showfullpath=0, $notooltip=0)
Return clickable name (possibility with the pictogram)
Parent class of all other business classes (invoices, contracts, proposals, orders, ...)
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
update($id, $user)
Update properties of a warehouse.
create($user)
Creation d&#39;un entrepot en base.
Class to manage warehouses.