24 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/entrepot.class.php';
43 public $cache_warehouses = array();
44 public $cache_lot = array();
45 public $cache_workstations = array();
76 public function loadWarehouses($fk_product = 0, $batch =
'', $status =
'', $sumStock =
true, $exclude = array(), $stockMin =
false, $orderBy =
'e.ref')
80 if (empty($fk_product) && count($this->cache_warehouses)) {
84 $warehouseStatus = array();
86 if (preg_match(
'/warehouseclosed/', $status)) {
89 if (preg_match(
'/warehouseopen/', $status)) {
92 if (preg_match(
'/warehouseinternal/', $status)) {
96 $sql =
"SELECT e.rowid, e.ref as label, e.description, e.fk_parent";
97 if (!empty($fk_product) && $fk_product > 0) {
99 $sql .=
", pb.qty as stock";
101 $sql .=
", ps.reel as stock";
103 } elseif ($sumStock) {
104 $sql .=
", sum(ps.reel) as stock";
106 $sql .=
" FROM ".$this->db->prefix().
"entrepot as e";
107 $sql .=
" LEFT JOIN ".$this->db->prefix().
"product_stock as ps on ps.fk_entrepot = e.rowid";
108 if (!empty($fk_product) && $fk_product > 0) {
109 $sql .=
" AND ps.fk_product = ".((int) $fk_product);
110 if (!empty($batch)) {
111 $sql .=
" LEFT JOIN ".$this->db->prefix().
"product_batch as pb on pb.fk_product_stock = ps.rowid AND pb.batch = '".$this->db->escape($batch).
"'";
114 $sql .=
" WHERE e.entity IN (".getEntity(
'stock').
")";
115 if (count($warehouseStatus)) {
116 $sql .=
" AND e.statut IN (".$this->db->sanitize(implode(
',', $warehouseStatus)).
")";
118 $sql .=
" AND e.statut = 1";
121 if (is_array($exclude) && !empty($exclude)) {
122 $sql .=
' AND e.rowid NOT IN('.$this->db->sanitize(implode(
',', $exclude)).
')';
126 if ($stockMin !==
false) {
127 if (!empty($fk_product) && $fk_product > 0) {
128 if (!empty($batch)) {
129 $sql .=
" AND pb.qty > ".((float) $stockMin);
131 $sql .=
" AND ps.reel > ".((float) $stockMin);
136 if ($sumStock && empty($fk_product)) {
137 $sql .=
" GROUP BY e.rowid, e.ref, e.description, e.fk_parent";
140 if ($stockMin !==
false) {
141 $sql .=
" HAVING sum(ps.reel) > ".((float) $stockMin);
144 $sql .=
" ORDER BY ".$orderBy;
146 dol_syslog(get_class($this).
'::loadWarehouses', LOG_DEBUG);
147 $resql = $this->db->query(
$sql);
149 $num = $this->db->num_rows($resql);
152 $obj = $this->db->fetch_object($resql);
156 $this->cache_warehouses[$obj->rowid][
'id'] = $obj->rowid;
157 $this->cache_warehouses[$obj->rowid][
'label'] = $obj->label;
158 $this->cache_warehouses[$obj->rowid][
'parent_id'] = $obj->fk_parent;
159 $this->cache_warehouses[$obj->rowid][
'description'] = $obj->description;
160 $this->cache_warehouses[$obj->rowid][
'stock'] = $obj->stock;
165 foreach ($this->cache_warehouses as $obj_rowid => $tab) {
166 $this->cache_warehouses[$obj_rowid][
'full_label'] = $this->
get_parent_path($tab);
188 global $conf, $langs;
190 if (empty($fk_product) && count($this->cache_workstations)) {
194 $sql =
"SELECT w.rowid, w.ref as ref, w.label as label, w.type, w.nb_operators_required,w.thm_operator_estimated,w.thm_machine_estimated";
195 $sql .=
" FROM ".$this->db->prefix().
"workstation_workstation as w";
196 $sql .=
" WHERE 1 = 1";
197 if (!empty($fk_product) && $fk_product > 0) {
198 $sql .=
" AND w.fk_product = ".((int) $fk_product);
200 $sql .=
" AND w.entity IN (".getEntity(
'workstation').
")";
202 if (is_array($exclude) && !empty($exclude)) {
203 $sql .=
' AND w.rowid NOT IN('.$this->db->sanitize(implode(
',', $exclude)).
')';
206 $sql .=
" ORDER BY ".$orderBy;
208 dol_syslog(get_class($this).
'::loadWorkstations', LOG_DEBUG);
209 $resql = $this->db->query(
$sql);
211 $num = $this->db->num_rows($resql);
214 $obj = $this->db->fetch_object($resql);
216 $this->cache_workstations[$obj->rowid][
'id'] = $obj->rowid;
217 $this->cache_workstations[$obj->rowid][
'ref'] = $obj->ref;
218 $this->cache_workstations[$obj->rowid][
'label'] = $obj->label;
219 $this->cache_workstations[$obj->rowid][
'type'] = $obj->type;
220 $this->cache_workstations[$obj->rowid][
'nb_operators_required'] = $obj->nb_operators_required;
221 $this->cache_workstations[$obj->rowid][
'thm_operator_estimated'] = $obj->thm_operator_estimated;
222 $this->cache_workstations[$obj->rowid][
'thm_machine_estimated'] = $obj->thm_machine_estimated;
244 if (empty($final_label)) {
245 $final_label = $tab[
'label'];
248 if (empty($tab[
'parent_id'])) {
251 if (!empty($this->cache_warehouses[$tab[
'parent_id']])) {
252 $final_label = $this->cache_warehouses[$tab[
'parent_id']][
'label'].
' >> '.$final_label;
253 return $this->
get_parent_path($this->cache_warehouses[$tab[
'parent_id']], $final_label);
286 public function selectWarehouses($selected =
'', $htmlname =
'idwarehouse', $filterstatus =
'', $empty = 0, $disabled = 0, $fk_product = 0, $empty_label =
'', $showstock = 0, $forcecombo = 0, $events = array(), $morecss =
'minwidth200', $exclude = array(), $showfullpath = 1, $stockMin =
false, $orderBy =
'e.ref', $multiselect = 0)
288 global $conf, $langs, $user, $hookmanager;
290 dol_syslog(get_class($this).
"::selectWarehouses $selected, $htmlname, $filterstatus, $empty, $disabled, $fk_product, $empty_label, $showstock, $forcecombo, $morecss", LOG_DEBUG);
293 if (empty($conf->global->ENTREPOT_EXTRA_STATUS)) {
296 if (!empty($fk_product) && $fk_product > 0) {
297 $this->cache_warehouses = array();
300 $this->
loadWarehouses($fk_product,
'', $filterstatus,
true, $exclude, $stockMin, $orderBy);
301 $nbofwarehouses = count($this->cache_warehouses);
303 if ($conf->use_javascript_ajax && !$forcecombo) {
304 include_once DOL_DOCUMENT_ROOT.
'/core/lib/ajax.lib.php';
306 $out .= $comboenhancement;
309 if (strpos($htmlname,
'search_') !== 0) {
310 if (empty($user->fk_warehouse) || $user->fk_warehouse == -1) {
311 if (is_scalar($selected) && ($selected ==
'-2' || $selected ==
'ifone') && !empty($conf->global->MAIN_DEFAULT_WAREHOUSE)) {
312 $selected = $conf->global->MAIN_DEFAULT_WAREHOUSE;
315 if (is_scalar($selected) && ($selected ==
'-2' || $selected ==
'ifone') && !empty($conf->global->MAIN_DEFAULT_WAREHOUSE_USER)) {
316 $selected = $user->fk_warehouse;
321 $out .=
'<select '.($multiselect ?
'multiple ' :
'').
'class="flat'.($morecss ?
' '.$morecss :
'').
'"'.($disabled ?
' disabled' :
'');
322 $out .=
' id="'.$htmlname.
'" name="'.($htmlname.($multiselect?
'[]':
'').($disabled ?
'_disabled' :
'')).
'"';
326 $out .=
'<option value="-1">'.($empty_label ? $empty_label :
' ').
'</option>';
328 foreach ($this->cache_warehouses as $id => $arraytypes) {
331 $label .= $arraytypes[
'full_label'];
333 $label .= $arraytypes[
'label'];
335 if (($fk_product || ($showstock > 0)) && ($arraytypes[
'stock'] != 0 || ($showstock > 0))) {
336 if ($arraytypes[
'stock'] <= 0) {
337 $label .=
' <span class="text-warning">('.$langs->trans(
"Stock").
':'.$arraytypes[
'stock'].
')</span>';
339 $label .=
' <span class="opacitymedium">('.$langs->trans(
"Stock").
':'.$arraytypes[
'stock'].
')</span>';
343 $out .=
'<option value="'.$id.
'"';
344 if (is_array($selected)) {
345 if (in_array($id, $selected)) {
349 if ($selected == $id || (preg_match(
'/^ifone/', $selected) && $nbofwarehouses == 1)) {
353 $out .=
' data-html="'.dol_escape_htmltag($label).
'"';
360 $out .=
'<input type="hidden" name="'.$htmlname.
'" value="'.(($selected > 0) ? $selected :
'').
'">';
364 'selected' => $selected,
365 'htmlname' => $htmlname,
366 'filterstatus' => $filterstatus,
368 'disabled ' => $disabled,
369 'fk_product' => $fk_product,
370 'empty_label' => $empty_label,
371 'showstock' => $showstock,
372 'forcecombo' => $forcecombo,
374 'morecss' => $morecss,
375 'exclude' => $exclude,
376 'showfullpath' => $showfullpath,
377 'stockMin' => $stockMin,
378 'orderBy' => $orderBy
381 $reshook = $hookmanager->executeHooks(
'selectWarehouses', $parameters, $this);
383 $out = $hookmanager->resPrint;
384 } elseif ($reshook == 0) {
385 $out .= $hookmanager->resPrint;
410 public function selectWorkstations($selected =
'', $htmlname =
'idworkstations', $empty = 0, $disabled = 0, $fk_product = 0, $empty_label =
'', $forcecombo = 0, $events = array(), $morecss =
'minwidth200', $exclude = array(), $showfullpath = 1, $orderBy =
'e.ref')
412 global $conf, $langs, $user, $hookmanager;
414 dol_syslog(get_class($this).
"::selectWorkstations $selected, $htmlname, $empty, $disabled, $fk_product, $empty_label, $forcecombo, $morecss", LOG_DEBUG);
418 if (!empty($fk_product) && $fk_product > 0) {
419 $this->cache_workstations = array();
423 $nbofworkstations = count($this->cache_workstations);
425 if ($conf->use_javascript_ajax && !$forcecombo) {
426 include_once DOL_DOCUMENT_ROOT.
'/core/lib/ajax.lib.php';
428 $out .= $comboenhancement;
431 if (strpos($htmlname,
'search_') !== 0) {
432 if (empty($user->fk_workstation) || $user->fk_workstation == -1) {
433 if (($selected ==
'-2' || $selected ==
'ifone') && !empty($conf->global->MAIN_DEFAULT_WORKSTATION)) {
434 $selected = $conf->global->MAIN_DEFAULT_WORKSTATION;
437 if (($selected ==
'-2' || $selected ==
'ifone') && !empty($conf->global->MAIN_DEFAULT_WORKSTATION)) {
438 $selected = $user->fk_workstation;
443 $out .=
'<select class="flat'.($morecss ?
' '.$morecss :
'').
'"'.($disabled ?
' disabled' :
'').
' id="'.$htmlname.
'" name="'.($htmlname.($disabled ?
'_disabled' :
'')).
'">';
445 $out .=
'<option value="-1">'.($empty_label ? $empty_label :
' ').
'</option>';
447 foreach ($this->cache_workstations as $id => $arraytypes) {
448 $label = $arraytypes[
'label'];
450 $out .=
'<option value="'.$id.
'"';
451 if ($selected == $id || (preg_match(
'/^ifone/', $selected) && $nbofworkstations == 1)) {
454 $out .=
' data-html="'.dol_escape_htmltag($label).
'"';
461 $out .=
'<input type="hidden" name="'.$htmlname.
'" value="'.(($selected > 0) ? $selected :
'').
'">';
465 'selected' => $selected,
466 'htmlname' => $htmlname,
467 'filterstatus' => $filterstatus,
469 'disabled ' => $disabled,
470 'fk_product' => $fk_product,
471 'empty_label' => $empty_label,
472 'forcecombo' => $forcecombo,
474 'morecss' => $morecss,
475 'exclude' => $exclude,
476 'showfullpath' => $showfullpath,
477 'orderBy' => $orderBy
480 $reshook = $hookmanager->executeHooks(
'selectWorkstations', $parameters, $this);
482 $out = $hookmanager->resPrint;
483 } elseif ($reshook == 0) {
484 $out .= $hookmanager->resPrint;
502 if ($htmlname !=
"none") {
503 print
'<form method="POST" action="'.$page.
'">';
504 print
'<input type="hidden" name="action" value="setwarehouse">';
505 print
'<input type="hidden" name="token" value="'.newToken().
'">';
506 print
'<table class="nobordernopadding">';
510 print
'<td class="left"><input type="submit" class="button smallpaddingimp" value="'.$langs->trans(
"Modify").
'"></td>';
511 print
'</tr></table></form>';
514 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/entrepot.class.php';
515 $warehousestatic =
new Entrepot($this->db);
516 $warehousestatic->fetch($selected);
517 print $warehousestatic->getNomUrl();
537 public function select_measuring_units($name =
'measuring_units', $measuring_style =
'', $default =
'0', $adddefault = 0, $mode = 0)
555 public function selectMeasuringUnits($name =
'measuring_units', $measuring_style =
'', $default =
'0', $adddefault = 0, $mode = 0, $morecss =
'maxwidth125')
557 global $langs, $conf, $mysoc, $db;
559 $langs->load(
"other");
564 require_once DOL_DOCUMENT_ROOT.
'/core/class/cunits.class.php';
565 $measuringUnits =
new CUnits($db);
568 $filter[
't.active'] = 1;
569 if ($measuring_style) {
570 $filter[
't.unit_type'] = $measuring_style;
573 $result = $measuringUnits->fetchAll(
584 $return .=
'<select class="flat'.($morecss ?
' '.$morecss :
'').
'" name="'.$name.
'" id="'.$name.
'">';
585 if ($adddefault || $adddefault ===
'') {
586 $return .=
'<option value="0">'.($adddefault ? $langs->trans(
"Default") :
'').
'</option>';
589 foreach ($measuringUnits->records as $lines) {
590 $return .=
'<option value="';
592 $return .= $lines->short_label;
593 } elseif ($mode == 2) {
594 $return .= $lines->scale;
596 $return .= $lines->id;
599 if ($mode == 1 && $lines->short_label == $default) {
600 $return .=
' selected';
601 } elseif ($mode == 2 && $lines->scale == $default) {
602 $return .=
' selected';
603 } elseif ($mode == 0 && $lines->id == $default) {
604 $return .=
' selected';
607 if ($measuring_style ==
'time') {
608 $return .= $langs->trans(ucfirst($lines->label));
610 $return .= $langs->trans($lines->label);
612 $return .=
'</option>';
614 $return .=
'</select>';
636 $langs->load(
'products');
641 require_once DOL_DOCUMENT_ROOT.
'/core/class/cproductnature.class.php';
645 $filter[
't.active'] = 1;
647 $result = $productNature->fetchAll(
'',
'', 0, 0, $filter);
653 $return .=
'<select class="flat" name="'.$name.
'" id="'.$name.
'">';
654 if ($showempty || ($selected ==
'' || $selected ==
'-1')) {
655 $return .=
'<option value="-1"';
656 if ($selected ==
'' || $selected ==
'-1') {
657 $return .=
' selected';
659 $return .=
'></option>';
661 if (!empty($productNature->records) && is_array($productNature->records)) {
662 foreach ($productNature->records as $lines) {
663 $return .=
'<option value="';
665 $return .= $lines->label;
667 $return .= $lines->code;
672 if ($mode == 1 && $lines->label == $selected) {
673 $return .=
' selected';
674 } elseif ($lines->code == $selected) {
675 $return .=
' selected';
679 $return .= $langs->trans($lines->label);
680 $return .=
'</option>';
683 $return .=
'</select>';
709 public function selectLotStock($selected =
'', $htmlname =
'batch_id', $filterstatus =
'', $empty = 0, $disabled = 0, $fk_product = 0, $fk_entrepot = 0, $objectLines = array(), $empty_label =
'', $forcecombo = 0, $events = array(), $morecss =
'minwidth200')
711 global $conf, $langs;
713 dol_syslog(get_class($this).
"::selectLotStock $selected, $htmlname, $filterstatus, $empty, $disabled, $fk_product, $fk_entrepot, $empty_label, $forcecombo, $morecss", LOG_DEBUG);
716 $productIdArray = array();
717 if (!is_array($objectLines) || !count($objectLines)) {
718 if (!empty($fk_product) && $fk_product > 0) {
719 $productIdArray[] = (int) $fk_product;
722 foreach ($objectLines as $line) {
723 if ($line->fk_product) {
724 $productIdArray[] = $line->fk_product;
731 if ($conf->use_javascript_ajax && !$forcecombo) {
732 include_once DOL_DOCUMENT_ROOT.
'/core/lib/ajax.lib.php';
734 $out .= $comboenhancement;
737 $out .=
'<select class="flat'.($morecss ?
' '.$morecss :
'').
'"'.($disabled ?
' disabled' :
'').
' id="'.$htmlname.
'" name="'.($htmlname.($disabled ?
'_disabled' :
'')).
'">';
739 $out .=
'<option value="-1">'.($empty_label ? $empty_label :
' ').
'</option>';
741 if (!empty($fk_product) && $fk_product > 0) {
742 $productIdArray = array((
int) $fk_product);
744 foreach ($this->cache_lot as $key => $value) {
745 $productIdArray[] = $key;
749 foreach ($productIdArray as $productId) {
750 foreach ($this->cache_lot[$productId] as $id => $arraytypes) {
751 if (empty($fk_entrepot) || $fk_entrepot == $arraytypes[
'entrepot_id']) {
752 $label = $arraytypes[
'entrepot_label'].
' - ';
753 $label .= $arraytypes[
'batch'];
754 if ($arraytypes[
'qty'] <= 0) {
755 $label .=
' <span class=\'text-warning\'>('.$langs->trans(
"Stock").
' '.$arraytypes[
'qty'].
')</span>';
757 $label .=
' <span class=\'opacitymedium\'>('.$langs->trans(
"Stock").
' '.$arraytypes[
'qty'].
')</span>';
760 $out .=
'<option value="'.$id.
'"';
762 if ($selected == $id || ($selected ==
'ifone' && $nboflot == 1)) {
765 $out .=
' data-html="'.dol_escape_htmltag($label).
'"';
774 $out .=
'<input type="hidden" name="'.$htmlname.
'" value="'.(($selected > 0) ? $selected :
'').
'">';
792 public function selectLotDataList($htmlname =
'batch_id', $empty = 0, $fk_product = 0, $fk_entrepot = 0, $objectLines = array())
796 dol_syslog(get_class($this).
"::selectLotDataList $htmlname, $empty, $fk_product, $fk_entrepot", LOG_DEBUG);
799 $productIdArray = array();
800 if (!is_array($objectLines) || !count($objectLines)) {
801 if (!empty($fk_product) && $fk_product > 0) {
802 $productIdArray[] = (int) $fk_product;
805 foreach ($objectLines as $line) {
806 if ($line->fk_product) {
807 $productIdArray[] = $line->fk_product;
814 $out .=
'<datalist id="'.$htmlname.
'" >';
816 if (!empty($fk_product) && $fk_product > 0) {
817 $productIdArray = array((
int) $fk_product);
819 foreach ($this->cache_lot as $key => $value) {
820 $productIdArray[] = $key;
824 foreach ($productIdArray as $productId) {
825 if (array_key_exists($productId, $this->cache_lot)) {
826 foreach ($this->cache_lot[$productId] as $id => $arraytypes) {
827 if (empty($fk_entrepot) || $fk_entrepot == $arraytypes[
'entrepot_id']) {
828 $label = $arraytypes[
'entrepot_label'] .
' - ';
829 $label .= $arraytypes[
'batch'];
830 $out .=
'<option data-warehouse="'.dol_escape_htmltag($label).
'" value="' . $arraytypes[
'batch'] .
'">(' . $langs->trans(
'Stock Total') .
': ' . $arraytypes[
'qty'] .
')</option>';
835 $out .=
'</datalist>';
850 global $conf, $langs;
852 $cacheLoaded =
false;
853 if (empty($productIdArray)) {
855 $this->cache_lot = array();
858 if (count($productIdArray) && count($this->cache_lot)) {
860 foreach ($productIdArray as $productId) {
861 $cacheLoaded = !empty($this->cache_lot[$productId]) ? true :
false;
865 return count($this->cache_lot);
868 $this->cache_lot = array();
869 $productIdList = implode(
',', $productIdArray);
873 if (empty($hookmanager)) {
874 include_once DOL_DOCUMENT_ROOT .
'/core/class/hookmanager.class.php';
877 $hookmanager->initHooks(array(
'productdao'));
878 $parameters = array(
'productIdList' => $productIdList);
879 $reshook = $hookmanager->executeHooks(
'loadLotStock', $parameters, $this);
881 $this->error = $hookmanager->error;
884 if (!empty($hookmanager->resArray[
'batch_list']) && is_array($hookmanager->resArray[
'batch_list'])) {
885 $this->cache_lot = $hookmanager->resArray[
'batch_list'];
886 $batch_count = (int) $hookmanager->resArray[
'batch_count'];
892 $sql =
"SELECT pb.batch, pb.rowid, ps.fk_entrepot, pb.qty, e.ref as label, ps.fk_product";
893 $sql .=
" FROM ".$this->db->prefix().
"product_batch as pb";
894 $sql .=
" LEFT JOIN ".$this->db->prefix().
"product_stock as ps on ps.rowid = pb.fk_product_stock";
895 $sql .=
" LEFT JOIN ".$this->db->prefix().
"entrepot as e on e.rowid = ps.fk_entrepot AND e.entity IN (".
getEntity(
'stock').
")";
896 if (!empty($productIdList)) {
897 $sql .=
" WHERE ps.fk_product IN (".$this->db->sanitize($productIdList).
")";
899 $sql .=
" ORDER BY e.ref, pb.batch";
901 dol_syslog(get_class($this).
'::loadLotStock', LOG_DEBUG);
902 $resql = $this->db->query(
$sql);
904 $num = $this->db->num_rows($resql);
907 $obj = $this->db->fetch_object($resql);
908 $this->cache_lot[$obj->fk_product][$obj->rowid][
'id'] = $obj->rowid;
909 $this->cache_lot[$obj->fk_product][$obj->rowid][
'batch'] = $obj->batch;
910 $this->cache_lot[$obj->fk_product][$obj->rowid][
'entrepot_id'] = $obj->fk_entrepot;
911 $this->cache_lot[$obj->fk_product][$obj->rowid][
'entrepot_label'] = $obj->label;
912 $this->cache_lot[$obj->fk_product][$obj->rowid][
'qty'] = $obj->qty;
916 return $batch_count + $num;