dolibarr  17.0.4
reassortlot.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2001-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2016 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005-2018 Regis Houssin <regis.houssin@inodbox.com>
5  * Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
6  * Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
7  * Copyright (C) 2016 Ferran Marcet <fmarcet@2byte.es>
8  * Copyright (C) 2019 Juanjo Menent <jmenent@2byte.es>
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 // Load Dolibarr environment
31 require '../main.inc.php';
32 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php';
34 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
35 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
36 require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
37 require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php';
38 
39 // Load translation files required by the page
40 $langs->loadLangs(array('products', 'stocks', 'productbatch'));
41 
42 $action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ...
43 $massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
44 $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'myobjectlist'; // To manage different context of search
45 $backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
46 $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
47 $mode = GETPOST('mode', 'aZ');
48 
49 $sref = GETPOST("sref", 'alpha');
50 $snom = GETPOST("snom", 'alpha');
51 $sall = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'));
52 $type = GETPOSTISSET('type') ? GETPOST('type', 'int') : Product::TYPE_PRODUCT;
53 $search_barcode = GETPOST("search_barcode", 'alpha');
54 $search_warehouse = GETPOST('search_warehouse', 'alpha');
55 $search_batch = GETPOST('search_batch', 'alpha');
56 $search_toolowstock = GETPOST('search_toolowstock');
57 $search_subjecttolotserial = GETPOST('search_subjecttolotserial');
58 $tosell = GETPOST("tosell");
59 $tobuy = GETPOST("tobuy");
60 $fourn_id = GETPOST("fourn_id", 'int');
61 $sbarcode = GETPOST("sbarcode", 'int');
62 $search_stock_physique = GETPOST('search_stock_physique', 'alpha');
63 
64 // Load variable for pagination
65 $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
66 $sortfield = GETPOST('sortfield', 'aZ09comma');
67 $sortorder = GETPOST('sortorder', 'aZ09comma');
68 $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
69 if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
70  // If $page is not defined, or '' or -1 or if we click on clear filters
71  $page = 0;
72 }
73 $offset = $limit * $page;
74 $pageprev = $page - 1;
75 $pagenext = $page + 1;
76 
77 // Initialize array of search criterias
78 $object = new Product($db);
79 $search_sale = GETPOST("search_sale");
80 if (GETPOSTISSET('catid')) {
81  $search_categ = GETPOST('catid', 'int');
82 } else {
83  $search_categ = GETPOST('search_categ', 'int');
84 }
85 
86 // Fetch optionals attributes and labels
87 $extrafields->fetch_name_optionals_label($object->table_element);
88 //$extrafields->fetch_name_optionals_label($object->table_element_line);
89 
90 $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
91 
92 // Default sort order (if not yet defined by previous GETPOST)
93 if (!$sortfield) {
94  reset($object->fields); // Reset is required to avoid key() to return null.
95  $sortfield = "p.".key($object->fields); // Set here default search field. By default 1st field in definition.
96 }
97 if (!$sortorder) {
98  $sortorder = "ASC";
99 }
100 
101 
102 // Initialize array of search criterias
103 $search = array();
104 foreach ($object->fields as $key => $val) {
105  if (GETPOST('search_'.$key, 'alpha') !== '') {
106  $search[$key] = GETPOST('search_'.$key, 'alpha');
107  }
108  if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
109  $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_'.$key.'_dtstartmonth', 'int'), GETPOST('search_'.$key.'_dtstartday', 'int'), GETPOST('search_'.$key.'_dtstartyear', 'int'));
110  $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int'));
111  }
112 }
113 $key = 'sellby';
114 $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_'.$key.'_dtstartmonth', 'int'), GETPOST('search_'.$key.'_dtstartday', 'int'), GETPOST('search_'.$key.'_dtstartyear', 'int'));
115 $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int'));
116 $key = 'eatby';
117 $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_'.$key.'_dtstartmonth', 'int'), GETPOST('search_'.$key.'_dtstartday', 'int'), GETPOST('search_'.$key.'_dtstartyear', 'int'));
118 $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int'));
119 
120 // Get object canvas (By default, this is not defined, so standard usage of dolibarr)
121 $canvas = GETPOST("canvas");
122 $objcanvas = null;
123 if (!empty($canvas)) {
124  require_once DOL_DOCUMENT_ROOT.'/core/class/canvas.class.php';
125  $objcanvas = new Canvas($db, $action);
126  $objcanvas->getCanvas('product', 'list', $canvas);
127 }
128 
129 // Security check
130 if ($user->socid) {
131  $socid = $user->socid;
132 }
133 $result = restrictedArea($user, 'produit|service', 0, 'product&product');
134 
135 $hookmanager->initHooks(array('reassortlotlist'));
136 
137 
138 /*
139  * Actions
140  */
141 
142 if (GETPOST('cancel', 'alpha')) {
143  $action = 'list';
144  $massaction = '';
145 }
146 if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
147  $massaction = '';
148 }
149 
150 $parameters = array();
151 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
152 if ($reshook < 0) {
153  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
154 }
155 
156 if (empty($reshook)) {
157  // Selection of new fields
158  include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
159 
160  // Purge search criteria
161  if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
162  foreach ($object->fields as $key => $val) {
163  $search[$key] = '';
164  if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
165  $search[$key.'_dtstart'] = '';
166  $search[$key.'_dtend'] = '';
167  }
168  }
169  $search['sellby_dtstart'] = '';
170  $search['eatby_dtstart'] = '';
171  $search['sellby_dtend'] = '';
172  $search['eatby_dtend'] = '';
173  $sref = "";
174  $snom = "";
175  $sall = "";
176  $tosell = "";
177  $tobuy = "";
178  $search_sale = "";
179  $search_categ = "";
180  $search_toolowstock = '';
181  $search_subjecttolotserial = '';
182  $search_batch = '';
183  $search_warehouse = '';
184  $fourn_id = '';
185  $sbarcode = '';
186  $search_stock_physique = '';
187  $toselect = array();
188  $search_array_options = array();
189  }
190  if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
191  || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
192  $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
193  }
194 
195  // Mass actions
196  /*$objectclass = 'MyObject';
197  $objectlabel = 'MyObject';
198  $uploaddir = $conf->mymodule->dir_output;
199  include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
200  */
201 }
202 
203 
204 
205 /*
206  * View
207  */
208 
209 $form = new Form($db);
210 $htmlother = new FormOther($db);
211 
212 $now = dol_now();
213 
214 $helpurl = 'EN:Module_Stocks_En|FR:Module_Stock|ES:M&oacute;dulo_Stocks';
215 $title = $langs->trans("ProductsAndServices");
216 $morejs = array();
217 $morecss = array();
218 
219 $sql = 'SELECT p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity,';
220 $sql .= ' p.fk_product_type, p.tms as datem,';
221 $sql .= ' p.duration, p.tosell as statut, p.tobuy, p.seuil_stock_alerte, p.desiredstock, p.stock, p.tosell, p.tobuy, p.tobatch,';
222 $sql .= ' ps.fk_entrepot, ps.reel,';
223 $sql .= ' e.ref as warehouse_ref, e.lieu as warehouse_lieu, e.fk_parent as warehouse_parent,';
224 $sql .= ' pb.batch, pb.eatby as oldeatby, pb.sellby as oldsellby,';
225 $sql .= ' pl.rowid as lotid, pl.eatby, pl.sellby,';
226 $sql .= ' SUM(pb.qty) as stock_physique, COUNT(pb.rowid) as nbinbatchtable';
227 $sql .= ' FROM '.MAIN_DB_PREFIX.'product as p';
228 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_stock as ps on p.rowid = ps.fk_product'; // Detail for each warehouse
229 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'entrepot as e on ps.fk_entrepot = e.rowid'; // Link on unique key
230 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_batch as pb on pb.fk_product_stock = ps.rowid'; // Detail for each lot on each warehouse
231 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_lot as pl on pl.fk_product = p.rowid AND pl.batch = pb.batch'; // Link on unique key
232 $sql .= " WHERE p.entity IN (".getEntity('product').") AND e.entity IN (".getEntity('stock').")";
233 if (!empty($search_categ) && $search_categ != '-1') {
234  $sql .= " AND ";
235  if ($search_categ == -2) {
236  $sql .= " NOT EXISTS ";
237  } else {
238  $sql .= " EXISTS ";
239  }
240  $sql .= "(";
241  $sql .= " SELECT cp.fk_categorie, cp.fk_product";
242  $sql .= " FROM " . MAIN_DB_PREFIX . "categorie_product as cp";
243  $sql .= " WHERE cp.fk_product = p.rowid"; // Join for the needed table to filter by categ
244  if ($search_categ > 0) {
245  $sql .= " AND cp.fk_categorie = " . ((int) $search_categ);
246  }
247  $sql .= ")";
248 }
249 if ($sall) {
250  $sql .= natural_search(array('p.ref', 'p.label', 'p.description', 'p.note'), $sall);
251 }
252 // if the type is not 1, we show all products (type = 0,2,3)
253 if (dol_strlen($type)) {
254  if ($type == 1) {
255  $sql .= " AND p.fk_product_type = '1'";
256  } else {
257  $sql .= " AND p.fk_product_type <> '1'";
258  }
259 }
260 if ($search_subjecttolotserial) {
261  $sql .= " AND p.tobatch > 0";
262 }
263 if ($sref) {
264  $sql .= natural_search("p.ref", $sref);
265 }
266 if ($search_barcode) {
267  $sql .= natural_search("p.barcode", $search_barcode);
268 }
269 if ($snom) {
270  $sql .= natural_search("p.label", $snom);
271 }
272 if (!empty($tosell)) {
273  $sql .= " AND p.tosell = ".((int) $tosell);
274 }
275 if (!empty($tobuy)) {
276  $sql .= " AND p.tobuy = ".((int) $tobuy);
277 }
278 if (!empty($canvas)) {
279  $sql .= " AND p.canvas = '".$db->escape($canvas)."'";
280 }
281 if ($fourn_id > 0) {
282  $sql .= " AND p.rowid = pf.fk_product AND pf.fk_soc = ".((int) $fourn_id);
283 }
284 if ($search_warehouse) {
285  $sql .= natural_search("e.ref", $search_warehouse);
286 }
287 if ($search_batch) {
288  $sql .= natural_search("pb.batch", $search_batch);
289 }
290 
291 foreach ($search as $key => $val) {
292  if (array_key_exists($key, $object->fields)) {
293  if ($key == 'status' && $search[$key] == -1) {
294  continue;
295  }
296  $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0);
297  if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) {
298  if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) {
299  $search[$key] = '';
300  }
301  $mode_search = 2;
302  }
303  if ($search[$key] != '') {
304  $sql .= natural_search("t.".$db->escape($key), $search[$key], (($key == 'status') ? 2 : $mode_search));
305  }
306  } else {
307  if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') {
308  $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key);
309  if ($columnName == 'eatby' || $columnName == 'sellby') {
310  if (preg_match('/_dtstart$/', $key)) {
311  $sql .= " AND pl.".$db->escape($columnName)." >= '".$db->idate($search[$key])."'";
312  }
313  if (preg_match('/_dtend$/', $key)) {
314  $sql .= " AND pl.".$db->escape($columnName)." <= '".$db->idate($search[$key])."'";
315  }
316  }
317  }
318  }
319 }
320 
321 $sql .= " GROUP BY p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity,";
322 $sql .= " p.fk_product_type, p.tms,";
323 $sql .= " p.duration, p.tosell, p.tobuy, p.seuil_stock_alerte, p.desiredstock, p.stock, p.tosell, p.tobuy, p.tobatch,";
324 $sql .= " ps.fk_entrepot, ps.reel,";
325 $sql .= " e.ref, e.lieu, e.fk_parent,";
326 $sql .= " pb.batch, pb.eatby, pb.sellby,";
327 $sql .= " pl.rowid, pl.eatby, pl.sellby";
328 $sql_having = '';
329 if ($search_toolowstock) {
330  $sql_having .= " HAVING SUM(".$db->ifsql('ps.reel IS NULL', '0', 'ps.reel').") < p.seuil_stock_alerte"; // Not used yet
331 }
332 if ($search_stock_physique != '') {
333  $natural_search_physique = natural_search('SUM(' . $db->ifsql('pb.qty IS NULL', $db->ifsql('ps.reel IS NULL', '0', 'ps.reel'), 'pb.qty') . ')', $search_stock_physique, 1, 1);
334  $natural_search_physique = " " . substr($natural_search_physique, 1, -1); // remove first "(" and last ")" characters
335  if (!empty($sql_having)) {
336  $sql_having .= " AND";
337  } else {
338  $sql_having .= " HAVING";
339  }
340  $sql_having .= $natural_search_physique;
341 }
342 if (!empty($sql_having)) {
343  $sql .= $sql_having;
344 }
345 
346 //print $sql;
347 
348 // Count total nb of records
349 $nbtotalofrecords = '';
350 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
351  $resql = $db->query($sql);
352  $nbtotalofrecords = $db->num_rows($resql);
353 
354  if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0
355  $page = 0;
356  $offset = 0;
357  }
358  $db->free($resql);
359 }
360 
361 // Complete request and execute it with limit
362 $sql .= $db->order($sortfield, $sortorder);
363 if ($limit) {
364  $sql .= $db->plimit($limit + 1, $offset);
365 }
366 
367 $resql = $db->query($sql);
368 if (!$resql) {
369  dol_print_error($db);
370  exit;
371 }
372 
373 $num = $db->num_rows($resql);
374 
375 $i = 0;
376 
377 if ($num == 1 && GETPOST('autojumpifoneonly') && ($sall or $snom or $sref)) {
378  $objp = $db->fetch_object($resql);
379  header("Location: card.php?id=$objp->rowid");
380  exit;
381 }
382 
383 if (isset($type)) {
384  if ($type == 1) {
385  $texte = $langs->trans("Services");
386  } else {
387  $texte = $langs->trans("Products");
388  }
389 } else {
390  $texte = $langs->trans("ProductsAndServices");
391 }
392 $texte .= ' ('.$langs->trans("StocksByLotSerial").')';
393 
394 $param = '';
395 if (!empty($mode)) {
396  $param .= '&mode='.urlencode($mode);
397 }
398 if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
399  $param .= '&contextpage='.urlencode($contextpage);
400 }
401 if ($limit > 0 && $limit != $conf->liste_limit) {
402  $param .= '&limit='.urlencode($limit);
403 }
404 foreach ($search as $key => $val) {
405  if (is_array($search[$key]) && count($search[$key])) {
406  foreach ($search[$key] as $skey) {
407  if ($skey != '') {
408  $param .= '&search_'.$key.'[]='.urlencode($skey);
409  }
410  }
411  } elseif ($search[$key] != '') {
412  $param .= '&search_'.$key.'='.urlencode($search[$key]);
413  }
414 }
415 if ($optioncss != '') {
416  $param .= '&optioncss='.urlencode($optioncss);
417 }
418 if ($sall) {
419  $param .= "&sall=".urlencode($sall);
420 }
421 if ($tosell) {
422  $param .= "&tosell=".urlencode($tosell);
423 }
424 if ($tobuy) {
425  $param .= "&tobuy=".urlencode($tobuy);
426 }
427 if ($type != '') {
428  $param .= "&type=".urlencode($type);
429 }
430 if ($fourn_id) {
431  $param .= "&fourn_id=".urlencode($fourn_id);
432 }
433 if ($snom) {
434  $param .= "&snom=".urlencode($snom);
435 }
436 if ($sref) {
437  $param .= "&sref=".urlencode($sref);
438 }
439 if ($search_batch) {
440  $param .= "&search_batch=".urlencode($search_batch);
441 }
442 if ($sbarcode) {
443  $param .= "&sbarcode=".urlencode($sbarcode);
444 }
445 if ($search_warehouse) {
446  $param .= "&search_warehouse=".urlencode($search_warehouse);
447 }
448 if ($search_toolowstock) {
449  $param .= "&search_toolowstock=".urlencode($search_toolowstock);
450 }
451 if ($search_subjecttolotserial) {
452  $param .= "&search_subjecttolotserial=".urlencode($search_subjecttolotserial);
453 }
454 if ($search_sale) {
455  $param .= "&search_sale=".urlencode($search_sale);
456 }
457 if (!empty($search_categ) && $search_categ != '-1') {
458  $param .= "&search_categ=".urlencode($search_categ);
459 }
460 if ($search_stock_physique) {
461  $param .= '&search_stock_physique=' . urlencode($search_stock_physique);
462 }
463 /*if ($eatby) $param.="&eatby=".$eatby;
464 if ($sellby) $param.="&sellby=".$sellby;*/
465 
466 llxHeader("", $title, $helpurl, $texte);
467 
468 print '<form id="searchFormList" action="'.$_SERVER["PHP_SELF"].'" method="POST" name="formulaire">'."\n";
469 if ($optioncss != '') {
470  print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
471 }
472 print '<input type="hidden" name="token" value="'.newToken().'">';
473 print '<input type="hidden" name="action" value="list">';
474 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
475 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
476 print '<input type="hidden" name="type" value="'.$type.'">';
477 print '<input type="hidden" name="page" value="'.$page.'">';
478 print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
479 print '<input type="hidden" name="mode" value="'.$mode.'">';
480 
481 print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'product', 0, '', '', $limit, 0, 0, 1);
482 
483 
484 if ($search_categ > 0) {
485  print "<div id='ways'>";
486  $c = new Categorie($db);
487  $c->fetch($search_categ);
488  $ways = $c->print_all_ways(' &gt; ', 'product/reassortlot.php');
489  print " &gt; ".$ways[0]."<br>\n";
490  print "</div><br>";
491 }
492 
493 // Filter on categories
494 $moreforfilter = '';
495 if (isModEnabled('categorie')) {
496  $moreforfilter .= '<div class="divsearchfield">';
497  $moreforfilter .= img_picto($langs->trans('Categories'), 'category', 'class="pictofixedwidth"');
498  $moreforfilter .= $htmlother->select_categories(Categorie::TYPE_PRODUCT, $search_categ, 'search_categ', 1);
499  $moreforfilter .= '</div>';
500 }
501 $moreforfilter.='<label for="search_subjecttolotserial">'.$langs->trans("SubjectToLotSerialOnly").' </label><input type="checkbox" id="search_subjecttolotserial" name="search_subjecttolotserial" value="1"'.($search_subjecttolotserial?' checked':'').'>';
502 
503 if (!empty($moreforfilter)) {
504  print '<div class="liste_titre liste_titre_bydiv centpercent">';
505  print $moreforfilter;
506  $parameters = array();
507  $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
508  print $hookmanager->resPrint;
509  print '</div>';
510 }
511 
512 
513 print '<div class="div-table-responsive">';
514 print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">';
515 
516 // Fields title search
517 // --------------------------------------------------------------------
518 print '<tr class="liste_titre_filter">';
519 // Action column
520 if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
521  print '<td class="liste_titre maxwidthsearch">';
522  $searchpicto = $form->showFilterButtons();
523  print $searchpicto;
524  print '</td>';
525 }
526 print '<td class="liste_titre">';
527 print '<input class="flat" type="text" name="sref" size="6" value="'.$sref.'">';
528 print '</td>';
529 print '<td class="liste_titre">';
530 print '<input class="flat" type="text" name="snom" size="8" value="'.$snom.'">';
531 print '</td>';
532 if (isModEnabled("service") && $type == 1) {
533  print '<td class="liste_titre">';
534  print '&nbsp;';
535  print '</td>';
536 }
537 print '<td class="liste_titre"><input class="flat" type="text" name="search_warehouse" size="6" value="'.$search_warehouse.'"></td>';
538 print '<td class="liste_titre center"><input class="flat" type="text" name="search_batch" size="6" value="'.$search_batch.'"></td>';
539 if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
540  print '<td class="liste_titre center">';
541  $key = 'sellby';
542  print '<div class="nowrap">';
543  print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
544  print '</div>';
545  print '<div class="nowrap">';
546  print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
547  print '</div>';
548  print '</td>';
549 }
550 if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
551  print '<td class="liste_titre center">';
552  $key = 'eatby';
553  print '<div class="nowrap">';
554  print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
555  print '</div>';
556  print '<div class="nowrap">';
557  print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
558  print '</div>';
559  print '</td>';
560 }
561 // Physical stock
562 print '<td class="liste_titre right">';
563 print '<input class="flat" type="text" size="5" name="search_stock_physique" value="'.dol_escape_htmltag($search_stock_physique).'">';
564 print '</td>';
565 print '<td class="liste_titre">&nbsp;</td>';
566 print '<td class="liste_titre">&nbsp;</td>';
567 print '<td class="liste_titre">&nbsp;</td>';
568 // Action column
569 if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
570  print '<td class="liste_titre maxwidthsearch">';
571  $searchpicto = $form->showFilterButtons();
572  print $searchpicto;
573  print '</td>';
574 }
575 print '</tr>'."\n";
576 
577 $totalarray = array();
578 $totalarray['nbfield'] = 0;
579 
580 // Fields title label
581 // --------------------------------------------------------------------
582 print '<tr class="liste_titre">';
583 // Action column
584 if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
586 }
587 print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "p.ref", '', $param, "", $sortfield, $sortorder);
588 print_liste_field_titre("Label", $_SERVER["PHP_SELF"], "p.label", '', $param, "", $sortfield, $sortorder);
589 if (isModEnabled("service") && $type == 1) {
590  print_liste_field_titre("Duration", $_SERVER["PHP_SELF"], "p.duration", '', $param, "", $sortfield, $sortorder, 'center ');
591 }
592 print_liste_field_titre("Warehouse", $_SERVER["PHP_SELF"], "e.ref", '', $param, "", $sortfield, $sortorder);
593 //print_liste_field_titre("DesiredStock", $_SERVER["PHP_SELF"], "p.desiredstock",$param,"",'',$sortfield,$sortorder, 'right );
594 print_liste_field_titre("Batch", $_SERVER["PHP_SELF"], "pb.batch", '', $param, "", $sortfield, $sortorder, 'center ');
595 if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
596  print_liste_field_titre("SellByDate", $_SERVER["PHP_SELF"], "pl.sellby", '', $param, "", $sortfield, $sortorder, 'center ');
597 }
598 if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
599  print_liste_field_titre("EatByDate", $_SERVER["PHP_SELF"], "pl.eatby", '', $param, "", $sortfield, $sortorder, 'center ');
600 }
601 print_liste_field_titre("PhysicalStock", $_SERVER["PHP_SELF"], "stock_physique", '', $param, "", $sortfield, $sortorder, 'right ');
602 // TODO Add info of running suppliers/customers orders
603 //print_liste_field_titre("TheoreticalStock",$_SERVER["PHP_SELF"], "stock_theorique",$param,"",'',$sortfield,$sortorder, 'right ');
605 print_liste_field_titre("ProductStatusOnSell", $_SERVER["PHP_SELF"], "p.tosell", "", $param, '', $sortfield, $sortorder, 'right ');
606 print_liste_field_titre("ProductStatusOnBuy", $_SERVER["PHP_SELF"], "p.tobuy", "", $param, '', $sortfield, $sortorder, 'right ');
607 if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
609 }
610 print "</tr>\n";
611 
612 $product_static = new Product($db);
613 $product_lot_static = new Productlot($db);
614 $warehousetmp = new Entrepot($db);
615 
616 // Loop on record
617 // --------------------------------------------------------------------
618 $i = 0;
619 $savnbfield = $totalarray['nbfield'];
620 $totalarray['nbfield'] = 0;
621 $imaxinloop = ($limit ? min($num, $limit) : $num);
622 while ($i < $imaxinloop) {
623  $objp = $db->fetch_object($resql);
624 
625  // Multilangs
626  if (getDolGlobalInt('MAIN_MULTILANGS')) { // si l'option est active
627  // TODO Use a cache
628  $sql = "SELECT label";
629  $sql .= " FROM ".MAIN_DB_PREFIX."product_lang";
630  $sql .= " WHERE fk_product = ".((int) $objp->rowid);
631  $sql .= " AND lang = '".$db->escape($langs->getDefaultLang())."'";
632  $sql .= " LIMIT 1";
633 
634  $result = $db->query($sql);
635  if ($result) {
636  $objtp = $db->fetch_object($result);
637  if (!empty($objtp->label)) {
638  $objp->label = $objtp->label;
639  }
640  }
641  }
642 
643  $product_static->ref = $objp->ref;
644  $product_static->id = $objp->rowid;
645  $product_static->label = $objp->label;
646  $product_static->type = $objp->fk_product_type;
647  $product_static->entity = $objp->entity;
648  $product_static->status = $objp->tosell;
649  $product_static->status_buy = $objp->tobuy;
650  $product_static->status_batch = $objp->tobatch;
651 
652  $product_lot_static->batch = $objp->batch;
653  $product_lot_static->fk_product = $objp->rowid;
654  $product_lot_static->id = $objp->lotid;
655  $product_lot_static->eatby = $objp->eatby;
656  $product_lot_static->sellby = $objp->sellby;
657 
658 
659  $warehousetmp->id = $objp->fk_entrepot;
660  $warehousetmp->ref = $objp->warehouse_ref;
661  $warehousetmp->label = $objp->warehouse_ref;
662  $warehousetmp->fk_parent = $objp->warehouse_parent;
663 
664  print '<tr>';
665 
666  // Action column
667  if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
668  print '<td></td>';
669  }
670 
671  // Ref
672  print '<td class="nowrap">';
673  print $product_static->getNomUrl(1, '', 16);
674  //if ($objp->stock_theorique < $objp->seuil_stock_alerte) print ' '.img_warning($langs->trans("StockTooLow"));
675  print '</td>';
676 
677  // Label
678  print '<td>'.$objp->label.'</td>';
679 
680  if (isModEnabled("service") && $type == 1) {
681  print '<td class="center">';
682  $regs = array();
683  if (preg_match('/([0-9]+)y/i', $objp->duration, $regs)) {
684  print $regs[1].' '.$langs->trans("DurationYear");
685  } elseif (preg_match('/([0-9]+)m/i', $objp->duration, $regs)) {
686  print $regs[1].' '.$langs->trans("DurationMonth");
687  } elseif (preg_match('/([0-9]+)d/i', $objp->duration, $regs)) {
688  print $regs[1].' '.$langs->trans("DurationDay");
689  } else {
690  print $objp->duration;
691  }
692  print '</td>';
693  }
694  //print '<td class="right">'.$objp->stock_theorique.'</td>';
695  //print '<td class="right">'.$objp->seuil_stock_alerte.'</td>';
696  //print '<td class="right">'.$objp->desiredstock.'</td>';
697 
698  // Warehouse
699  print '<td class="nowrap">';
700  if ($objp->fk_entrepot > 0) {
701  print $warehousetmp->getNomUrl(1);
702  }
703  print '</td>';
704 
705  // Lot
706  print '<td class="center nowrap">';
707  if ($product_lot_static->batch) {
708  print $product_lot_static->getNomUrl(1);
709  }
710  print '</td>';
711 
712  if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
713  print '<td class="center">'.dol_print_date($db->jdate($objp->sellby), 'day').'</td>';
714  }
715 
716  if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
717  print '<td class="center">'.dol_print_date($db->jdate($objp->eatby), 'day').'</td>';
718  }
719 
720  print '<td class="right">';
721  //if ($objp->seuil_stock_alerte && ($objp->stock_physique < $objp->seuil_stock_alerte)) print img_warning($langs->trans("StockTooLow")).' ';
722  if (is_null($objp->stock_physique)) {
723  if (!empty($objp->reel)) {
724  print price2num($objp->reel, 'MS');
725  }
726  } else {
727  if (!empty($objp->stock_physique)) {
728  print price2num($objp->stock_physique, 'MS');
729  }
730  }
731  print '</td>';
732 
733  print '<td class="right">';
734  print img_picto($langs->trans("StockMovement"), 'movement', 'class="pictofixedwidth"');
735  print '<a href="'.DOL_URL_ROOT.'/product/stock/movement_list.php?idproduct='.$product_static->id.'&search_warehouse='.$objp->fk_entrepot.'&search_batch='.($objp->batch != 'Undefined' ? $objp->batch : 'Undefined').'">'.$langs->trans("Movements").'</a>';
736  print '</td>';
737 
738  print '<td class="right nowrap">'.$product_static->LibStatut($objp->statut, 5, 0).'</td>';
739 
740  print '<td class="right nowrap">'.$product_static->LibStatut($objp->tobuy, 5, 1).'</td>';
741 
742  // Action column
743  if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
744  print '<td></td>';
745  }
746 
747  print "</tr>\n";
748  $i++;
749 }
750 
751 $db->free($resql);
752 
753 print '</table>'."\n";
754 print '</div>'."\n";
755 
756 print '</form>'."\n";
757 
758 
759 // End of page
760 llxFooter();
761 $db->close();
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:56
llxFooter()
Empty footer.
Definition: wrapper.php:70
Class to manage canvas.
Class to manage categories.
Class to manage warehouses.
Class to manage generation of HTML components Only common components must be here.
Classe permettant la generation de composants html autre Only common components are here.
Class to manage products or services.
Class with list of lots and properties.
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
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
natural_search($fields, $value, $mode=0, $nofirstand=0)
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
print_barre_liste($titre, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $hideselectlimit=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
isModEnabled($module)
Is Dolibarr module enabled.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
$nbtotalofrecords
Count total nb of records.
Definition: list.php:329
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.