dolibarr  17.0.4
reassort.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2001-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2015 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) 2019 Juanjo Menent <jmenent@2byte.es>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <https://www.gnu.org/licenses/>.
21  */
22 
29 // Load Dolibarr environment
30 require '../main.inc.php';
31 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
34 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
35 
36 // Load translation files required by the page
37 $langs->loadLangs(array('products', 'stocks'));
38 
39 $action = GETPOST('action', 'aZ09');
40 $sref = GETPOST("sref", 'alpha');
41 $snom = GETPOST("snom", 'alpha');
42 $sall = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'));
43 $type = GETPOSTISSET('type') ? GETPOST('type', 'int') : Product::TYPE_PRODUCT;
44 $search_barcode = GETPOST("search_barcode", 'alpha');
45 $search_toolowstock = GETPOST('search_toolowstock');
46 $tosell = GETPOST("tosell");
47 $tobuy = GETPOST("tobuy");
48 $fourn_id = GETPOST("fourn_id", 'int');
49 $sbarcode = GETPOST("sbarcode", 'int');
50 $search_stock_physique = GETPOST('search_stock_physique', 'alpha');
51 
52 $sortfield = GETPOST('sortfield', 'aZ09comma');
53 $sortorder = GETPOST('sortorder', 'aZ09comma');
54 $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
55 if (empty($page) || $page < 0) {
56  $page = 0;
57 }
58 if (!$sortfield) {
59  $sortfield = "p.ref";
60 }
61 if (!$sortorder) {
62  $sortorder = "ASC";
63 }
64 $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
65 if (empty($page) || $page == -1) {
66  $page = 0;
67 } // If $page is not defined, or '' or -1
68 $offset = $limit * $page;
69 
70 // Load sale and categ filters
71 $search_sale = GETPOST("search_sale");
72 if (GETPOSTISSET('catid')) {
73  $search_categ = GETPOST('catid', 'int');
74 } else {
75  $search_categ = GETPOST('search_categ', 'int');
76 }
77 
78 // Get object canvas (By default, this is not defined, so standard usage of dolibarr)
79 $canvas = GETPOST("canvas");
80 $objcanvas = null;
81 if (!empty($canvas)) {
82  require_once DOL_DOCUMENT_ROOT.'/core/class/canvas.class.php';
83  $objcanvas = new Canvas($db, $action);
84  $objcanvas->getCanvas('product', 'list', $canvas);
85 }
86 
87 // Define virtualdiffersfromphysical
88 $virtualdiffersfromphysical = 0;
89 if (!empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT)
90  || !empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)
91  || !empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)
92  || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION)
93  || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE)
94  || isModEnabled('mrp')) {
95  $virtualdiffersfromphysical = 1; // According to increase/decrease stock options, virtual and physical stock may differs.
96 }
97 
98 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
99 $hookmanager->initHooks(array('productreassortlist'));
100 
101 if ($user->socid) {
102  $socid = $user->socid;
103 }
104 $result = restrictedArea($user, 'produit|service', 0, 'product&product');
105 
106 $object = new Product($db);
107 
108 /*
109  * Actions
110  */
111 
112 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
113  $sref = "";
114  $snom = "";
115  $sall = "";
116  $tosell = "";
117  $tobuy = "";
118  $search_sale = "";
119  $search_categ = "";
120  $search_toolowstock = '';
121  $fourn_id = '';
122  $sbarcode = '';
123  $search_stock_physique = '';
124 }
125 
126 
127 
128 /*
129  * View
130  */
131 
132 $helpurl = 'EN:Module_Stocks_En|FR:Module_Stock|ES:M&oacute;dulo_Stocks';
133 
134 $form = new Form($db);
135 $htmlother = new FormOther($db);
136 
137 $sql = 'SELECT p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity,';
138 $sql .= ' p.fk_product_type, p.tms as datem,';
139 $sql .= ' p.duration, p.tosell as statut, p.tobuy, p.seuil_stock_alerte, p.desiredstock,';
140 $sql .= ' SUM(s.reel) as stock_physique';
141 if (!empty($conf->global->PRODUCT_USE_UNITS)) {
142  $sql .= ', u.short_label as unit_short';
143 }
144 // Add fields from hooks
145 $parameters = array();
146 $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
147 $sql .= $hookmanager->resPrint;
148 $sql .= ' FROM '.MAIN_DB_PREFIX.'product as p';
149 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_stock as s ON p.rowid = s.fk_product';
150 if (!empty($conf->global->PRODUCT_USE_UNITS)) {
151  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_units as u on p.fk_unit = u.rowid';
152 }
153 $sql .= " WHERE p.entity IN (".getEntity('product').")";
154 if (!empty($search_categ) && $search_categ != '-1') {
155  $sql .= " AND ";
156  if ($search_categ == -2) {
157  $sql .= " NOT EXISTS ";
158  } else {
159  $sql .= " EXISTS ";
160  }
161  $sql .= "(";
162  $sql .= " SELECT cp.fk_categorie, cp.fk_product";
163  $sql .= " FROM " . MAIN_DB_PREFIX . "categorie_product as cp";
164  $sql .= " WHERE cp.fk_product = p.rowid"; // Join for the needed table to filter by categ
165  if ($search_categ > 0) {
166  $sql .= " AND cp.fk_categorie = " . ((int) $search_categ);
167  }
168  $sql .= ")";
169 }
170 $sql .= " AND EXISTS (SELECT e.rowid FROM ".MAIN_DB_PREFIX."entrepot as e WHERE e.rowid = s.fk_entrepot AND e.entity IN (".getEntity('stock')."))";
171 if ($sall) {
172  $sql .= natural_search(array('p.ref', 'p.label', 'p.description', 'p.note'), $sall);
173 }
174 // if the type is not 1, we show all products (type = 0,2,3)
175 if (dol_strlen($type)) {
176  if ($type == 1) {
177  $sql .= " AND p.fk_product_type = '1'";
178  } else {
179  $sql .= " AND p.fk_product_type <> '1'";
180  }
181 }
182 if ($sref) {
183  $sql .= natural_search('p.ref', $sref);
184 }
185 if ($search_barcode) {
186  $sql .= natural_search('p.barcode', $search_barcode);
187 }
188 if ($snom) {
189  $sql .= natural_search('p.label', $snom);
190 }
191 if (!empty($tosell)) {
192  $sql .= " AND p.tosell = ".((int) $tosell);
193 }
194 if (!empty($tobuy)) {
195  $sql .= " AND p.tobuy = ".((int) $tobuy);
196 }
197 if (!empty($canvas)) {
198  $sql .= " AND p.canvas = '".$db->escape($canvas)."'";
199 }
200 if ($fourn_id > 0) {
201  $sql .= " AND p.rowid = pf.fk_product AND pf.fk_soc = ".((int) $fourn_id);
202 }
203 // Add where from hooks
204 $parameters = array();
205 $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook
206 $sql .= $hookmanager->resPrint;
207 $sql .= " GROUP BY p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity,";
208 $sql .= " p.fk_product_type, p.tms, p.duration, p.tosell, p.tobuy, p.seuil_stock_alerte, p.desiredstock";
209 // Add fields from hooks
210 $parameters = array();
211 $reshook = $hookmanager->executeHooks('printFieldSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
212 $sql .= $hookmanager->resPrint;
213 $sql_having = '';
214 if ($search_toolowstock) {
215  $sql_having .= " HAVING SUM(".$db->ifsql('s.reel IS NULL', '0', 's.reel').") < p.seuil_stock_alerte";
216 }
217 if ($search_stock_physique != '') {
218  //$natural_search_physique = natural_search('HAVING SUM(' . $db->ifsql('s.reel IS NULL', '0', 's.reel') . ')', $search_stock_physique, 1, 1);
219  $natural_search_physique = natural_search('SUM(' . $db->ifsql('s.reel IS NULL', '0', 's.reel') . ')', $search_stock_physique, 1, 1);
220  $natural_search_physique = " " . substr($natural_search_physique, 1, -1); // remove first "(" and last ")" characters
221  if (!empty($sql_having)) {
222  $sql_having .= " AND";
223  } else {
224  $sql_having .= " HAVING";
225  }
226  $sql_having .= $natural_search_physique;
227 }
228 if (!empty($sql_having)) {
229  $sql .= $sql_having;
230 }
231 $sql .= $db->order($sortfield, $sortorder);
232 
233 // Count total nb of records
234 $nbtotalofrecords = '';
235 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
236  $result = $db->query($sql);
237  $nbtotalofrecords = $db->num_rows($result);
238  if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
239  $page = 0;
240  $offset = 0;
241  }
242 }
243 
244 $sql .= $db->plimit($limit + 1, $offset);
245 
246 $resql = $db->query($sql);
247 if ($resql) {
248  $num = $db->num_rows($resql);
249 
250  $i = 0;
251 
252  if ($num == 1 && GETPOST('autojumpifoneonly') && ($sall || $snom || $sref)) {
253  $objp = $db->fetch_object($resql);
254  header("Location: card.php?id=$objp->rowid");
255  exit;
256  }
257 
258  if (isset($type)) {
259  if ($type == 1) {
260  $texte = $langs->trans("Services");
261  } else {
262  $texte = $langs->trans("Products");
263  }
264  } else {
265  $texte = $langs->trans("ProductsAndServices");
266  }
267  $texte .= ' ('.$langs->trans("MenuStocks").')';
268 
269  $param = '';
270  if ($limit > 0 && $limit != $conf->liste_limit) {
271  $param .= '&limit='.urlencode($limit);
272  }
273  if ($sall) {
274  $param .= "&sall=".urlencode($sall);
275  }
276  if ($tosell) {
277  $param .= "&tosell=".urlencode($tosell);
278  }
279  if ($tobuy) {
280  $param .= "&tobuy=".urlencode($tobuy);
281  }
282  if ($type != '') {
283  $param .= "&type=".urlencode($type);
284  }
285  if ($fourn_id) {
286  $param .= "&fourn_id=".urlencode($fourn_id);
287  }
288  if ($snom) {
289  $param .= "&snom=".urlencode($snom);
290  }
291  if ($sref) {
292  $param .= "&sref=".urlencode($sref);
293  }
294  if ($search_sale) {
295  $param .= "&search_sale=".urlencode($search_sale);
296  }
297  if ($search_categ > 0) {
298  $param .= "&search_categ=".urlencode($search_categ);
299  }
300  if ($search_toolowstock) {
301  $param .= "&search_toolowstock=".urlencode($search_toolowstock);
302  }
303  if ($sbarcode) {
304  $param .= "&sbarcode=".urlencode($sbarcode);
305  }
306  if ($search_stock_physique) {
307  $param .= '&search_stock_physique=' . urlencode($search_stock_physique);
308  }
309 
310  llxHeader("", $texte, $helpurl);
311 
312  print '<form action="'.$_SERVER["PHP_SELF"].'" method="post" name="formulaire">';
313  print '<input type="hidden" name="token" value="'.newToken().'">';
314  print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
315  print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
316  print '<input type="hidden" name="page" value="'.$page.'">';
317  print '<input type="hidden" name="type" value="'.$type.'">';
318 
319  print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'product', 0, '', '', $limit);
320 
321  if ($search_categ > 0) {
322  print "<div id='ways'>";
323  $c = new Categorie($db);
324  $c->fetch($search_categ);
325  $ways = $c->print_all_ways(' &gt; ', 'product/reassort.php');
326  print " &gt; ".$ways[0]."<br>\n";
327  print "</div><br>";
328  }
329 
330  // Filter on categories
331  $moreforfilter = '';
332  if (isModEnabled('categorie')) {
333  $moreforfilter .= '<div class="divsearchfield">';
334  $moreforfilter .= img_picto($langs->trans('Categories'), 'category', 'class="pictofixedwidth"');
335  $moreforfilter .= $htmlother->select_categories(Categorie::TYPE_PRODUCT, $search_categ, 'search_categ', 1);
336  $moreforfilter .= '</div>';
337  }
338 
339  $moreforfilter .= '<div class="divsearchfield">';
340  $moreforfilter .= '<label for="search_toolowstock">'.$langs->trans("StockTooLow").' </label><input type="checkbox" id="search_toolowstock" name="search_toolowstock" value="1"'.($search_toolowstock ? ' checked' : '').'>';
341  $moreforfilter .= '</div>';
342 
343  if (!empty($moreforfilter)) {
344  print '<div class="liste_titre liste_titre_bydiv centpercent">';
345  print $moreforfilter;
346  $parameters = array();
347  $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
348  print $hookmanager->resPrint;
349  print '</div>';
350  }
351 
352  $formProduct = new FormProduct($db);
353  $formProduct->loadWarehouses();
354  $warehouses_list = $formProduct->cache_warehouses;
355  $nb_warehouse = count($warehouses_list);
356  $colspan_warehouse = 1;
357  if (!empty($conf->global->STOCK_DETAIL_ON_WAREHOUSE)) {
358  $colspan_warehouse = $nb_warehouse > 1 ? $nb_warehouse + 1 : 1;
359  }
360 
361  print '<div class="div-table-responsive">';
362  print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'">';
363 
364  // Fields title search
365  print '<tr class="liste_titre_filter">';
366  // Action column
367  if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
368  print '<td class="liste_titre maxwidthsearch">';
369  $searchpicto = $form->showFilterAndCheckAddButtons(0);
370  print $searchpicto;
371  print '</td>';
372  }
373  print '<td class="liste_titre">';
374  print '<input class="flat" type="text" name="sref" size="6" value="'.$sref.'">';
375  print '</td>';
376  print '<td class="liste_titre">';
377  print '<input class="flat" type="text" name="snom" size="8" value="'.$snom.'">';
378  print '</td>';
379  // Duration
380  if (isModEnabled("service") && $type == 1) {
381  print '<td class="liste_titre">';
382  print '&nbsp;';
383  print '</td>';
384  }
385  // Stock limit
386  print '<td class="liste_titre">&nbsp;</td>';
387  print '<td class="liste_titre right">&nbsp;</td>';
388  // Physical stock
389  print '<td class="liste_titre right">';
390  print '<input class="flat" type="text" size="5" name="search_stock_physique" value="'.dol_escape_htmltag($search_stock_physique).'">';
391  print '</td>';
392  if ($virtualdiffersfromphysical) {
393  print '<td class="liste_titre">&nbsp;</td>';
394  }
395  print '<td class="liste_titre">&nbsp;</td>';
396  print '<td class="liste_titre" colspan="'.$colspan_warehouse.'">&nbsp;</td>';
397  print '<td class="liste_titre"></td>';
398  $parameters = array();
399  $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook
400  print $hookmanager->resPrint;
401  if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
402  print '<td class="liste_titre maxwidthsearch">';
403  $searchpicto = $form->showFilterAndCheckAddButtons(0);
404  print $searchpicto;
405  print '</td>';
406  }
407  print '</tr>';
408 
409  //Line for column titles
410  print "<tr class=\"liste_titre\">";
411  // Action column
412  if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
414  }
415  print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "p.ref", '', $param, "", $sortfield, $sortorder);
416  print_liste_field_titre("Label", $_SERVER["PHP_SELF"], "p.label", '', $param, "", $sortfield, $sortorder);
417  if (isModEnabled("service") && $type == 1) {
418  print_liste_field_titre("Duration", $_SERVER["PHP_SELF"], "p.duration", '', $param, "", $sortfield, $sortorder, 'center ');
419  }
420  print_liste_field_titre("StockLimit", $_SERVER["PHP_SELF"], "p.seuil_stock_alerte", '', $param, "", $sortfield, $sortorder, 'right ');
421  print_liste_field_titre("DesiredStock", $_SERVER["PHP_SELF"], "p.desiredstock", '', $param, "", $sortfield, $sortorder, 'right ');
422  print_liste_field_titre("PhysicalStock", $_SERVER["PHP_SELF"], "stock_physique", '', $param, "", $sortfield, $sortorder, 'right ');
423  // Details per warehouse
424  if (!empty($conf->global->STOCK_DETAIL_ON_WAREHOUSE)) { // TODO This should be moved into the selection of fields on page product/list (page product/stock will be removed and replaced with product/list with its own context)
425  if ($nb_warehouse > 1) {
426  foreach ($warehouses_list as &$wh) {
427  print_liste_field_titre($wh['label'], '', '', '', '', '', '', '', 'right ');
428  }
429  }
430  }
431  if ($virtualdiffersfromphysical) {
432  print_liste_field_titre("VirtualStock", $_SERVER["PHP_SELF"], "", '', $param, "", $sortfield, $sortorder, 'right ', 'VirtualStockDesc');
433  }
434  // Units
435  if (!empty($conf->global->PRODUCT_USE_UNITS)) {
436  print_liste_field_titre("Unit", $_SERVER["PHP_SELF"], "unit_short", '', $param, 'align="right"', $sortfield, $sortorder);
437  }
439  print_liste_field_titre("ProductStatusOnSell", $_SERVER["PHP_SELF"], "p.tosell", '', $param, "", $sortfield, $sortorder, 'right ');
440  print_liste_field_titre("ProductStatusOnBuy", $_SERVER["PHP_SELF"], "p.tobuy", '', $param, "", $sortfield, $sortorder, 'right ');
441  // Hook fields
442  $parameters = array('param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder);
443  $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook
444  print $hookmanager->resPrint;
445  // Action column
446  if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
448  }
449  print "</tr>\n";
450 
451  while ($i < min($num, $limit)) {
452  $objp = $db->fetch_object($resql);
453 
454  $product = new Product($db);
455  $product->fetch($objp->rowid);
456  $product->load_stock();
457 
458  print '<tr>';
459  // Action column
460  if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
461  print '<td></td>';
462  }
463  print '<td class="nowrap">';
464  print $product->getNomUrl(1, '', 16);
465  //if ($objp->stock_theorique < $objp->seuil_stock_alerte) print ' '.img_warning($langs->trans("StockTooLow"));
466  print '</td>';
467  print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($product->label).'">'.dol_escape_htmltag($product->label).'</td>';
468 
469  if (isModEnabled("service") && $type == 1) {
470  print '<td class="center">';
471  if (preg_match('/([0-9]+)y/i', $objp->duration, $regs)) {
472  print $regs[1].' '.$langs->trans("DurationYear");
473  } elseif (preg_match('/([0-9]+)m/i', $objp->duration, $regs)) {
474  print $regs[1].' '.$langs->trans("DurationMonth");
475  } elseif (preg_match('/([0-9]+)d/i', $objp->duration, $regs)) {
476  print $regs[1].' '.$langs->trans("DurationDay");
477  } else {
478  print $objp->duration;
479  }
480  print '</td>';
481  }
482  //print '<td class="right">'.$objp->stock_theorique.'</td>';
483  print '<td class="right">'.$objp->seuil_stock_alerte.'</td>';
484  print '<td class="right">'.$objp->desiredstock.'</td>';
485  // Real stock
486  print '<td class="right">';
487  if ($objp->seuil_stock_alerte != '' && ($objp->stock_physique < $objp->seuil_stock_alerte)) {
488  print img_warning($langs->trans("StockTooLow")).' ';
489  }
490  print price(price2num($objp->stock_physique, 'MS'), 0, $langs, 1, 0);
491  print '</td>';
492 
493  // Details per warehouse
494  if (!empty($conf->global->STOCK_DETAIL_ON_WAREHOUSE)) { // TODO This should be moved into the selection of fields on page product/list (page product/stock will be removed and replaced with product/list with its own context)
495  if ($nb_warehouse > 1) {
496  foreach ($warehouses_list as &$wh) {
497  print '<td class="right">';
498  print price(empty($product->stock_warehouse[$wh['id']]->real) ? 0 : price2num($product->stock_warehouse[$wh['id']]->real, 'MS'), 0, $langs, 1, 0);
499  print '</td>';
500  }
501  }
502  }
503 
504  // Virtual stock
505  if ($virtualdiffersfromphysical) {
506  print '<td class="right">';
507  if ($objp->seuil_stock_alerte != '' && ($product->stock_theorique < (float) $objp->seuil_stock_alerte)) {
508  print img_warning($langs->trans("StockTooLow")).' ';
509  }
510  print price(price2num($product->stock_theorique, 'MS'), 0, $langs, 1, 0);
511  print '</td>';
512  }
513  // Units
514  if (!empty($conf->global->PRODUCT_USE_UNITS)) {
515  print '<td class="left">'.$objp->unit_short.'</td>';
516  }
517  print '<td class="center nowraponall">';
518  print img_picto($langs->trans("StockMovement"), 'movement', 'class="pictofixedwidth"');
519  print '<a href="'.DOL_URL_ROOT.'/product/stock/movement_list.php?idproduct='.$product->id.'">'.$langs->trans("Movements").'</a>';
520  print '</td>';
521  print '<td class="right nowrap">'.$product->LibStatut($objp->statut, 5, 0).'</td>';
522  print '<td class="right nowrap">'.$product->LibStatut($objp->tobuy, 5, 1).'</td>';
523  // Fields from hook
524  $parameters = array('obj'=>$objp);
525  $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $product); // Note that $action and $object may have been modified by hook
526  print $hookmanager->resPrint;
527  // Action column
528  if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
529  print '<td></td>';
530  }
531 
532  print "</tr>\n";
533  $i++;
534  }
535 
536  print "</table>";
537  print '</div>';
538 
539  print '</form>';
540 
541  $db->free($resql);
542 } else {
543  dol_print_error($db);
544 }
545 
546 // End of page
547 llxFooter();
548 $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 generation of HTML components Only common components must be here.
Classe permettant la generation de composants html autre Only common components are here.
Class with static methods for building HTML components related to products Only components common to ...
Class to manage products or services.
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
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields.
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...
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
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.