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