dolibarr  16.0.5
list.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2001-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2016 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005-2014 Regis Houssin <regis.houssin@inodbox.com>
5  * Copyright (C) 2015 Juanjo Menent <jmenent@2byte.es>
6  * Copyright (C) 2020 Tobias Sekan <tobias.sekan@startmail.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
28 require '../../main.inc.php';
29 require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
30 
31 if (!empty($conf->categorie->enabled)) {
32  require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcategory.class.php';
33  require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
34 }
35 
36 // Load translation files required by the page
37 $langs->loadLangs(array("stocks", "other"));
38 
39 $action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ...
40 $massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
41 $show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk actions ?
42 $confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation
43 $cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button
44 $toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list
45 $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'stocklist'; // To manage different context of search
46 $backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
47 $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
48 $toselect = GETPOST('toselect', 'array');
49 
50 
51 $search_all = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'));
52 $search_ref = GETPOST("sref", "alpha") ?GETPOST("sref", "alpha") : GETPOST("search_ref", "alpha");
53 $search_label = GETPOST("snom", "alpha") ?GETPOST("snom", "alpha") : GETPOST("search_label", "alpha");
54 $search_status = GETPOST("search_status", "int");
55 
56 if (!empty($conf->categorie->enabled)) {
57  $search_category_list = GETPOST("search_category_".Categorie::TYPE_WAREHOUSE."_list", "array");
58 }
59 
60 // Load variable for pagination
61 $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
62 $sortfield = GETPOST('sortfield', 'aZ09comma');
63 $sortorder = GETPOST('sortorder', 'aZ09comma');
64 $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
65 if (empty($page) || $page == -1 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) {
66  $page = 0;
67 } // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action
68 $offset = $limit * $page;
69 $pageprev = $page - 1;
70 $pagenext = $page + 1;
71 if (!$sortfield) {
72  $sortfield = "t.ref";
73 }
74 if (!$sortorder) {
75  $sortorder = "ASC";
76 }
77 
78 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
79 $object = new Entrepot($db);
80 $extrafields = new ExtraFields($db);
81 $diroutputmassaction = $conf->stock->dir_output.'/temp/massgeneration/'.$user->id;
82 $hookmanager->initHooks(array('stocklist'));
83 
84 // Fetch optionals attributes and labels
85 $extrafields->fetch_name_optionals_label($object->table_element);
86 
87 $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
88 
89 
90 // Initialize array of search criterias
91 $search_all = GETPOST("search_all", 'alpha');
92 $search = array();
93 foreach ($object->fields as $key => $val) {
94  $search_key = $key;
95  if ($search_key == 'statut') {
96  $search_key = 'status'; // remove this after refactor entrepot.class property statut to status
97  }
98  if (GETPOST('search_'.$search_key, 'alpha') !== '') {
99  $search[$search_key] = GETPOST('search_'.$search_key, 'alpha');
100  }
101 }
102 
103 // List of fields to search into when doing a "search in all"
104 $fieldstosearchall = array();
105 foreach ($object->fields as $key => $val) {
106  if (!empty($val['searchall'])) {
107  $fieldstosearchall['t.'.$key] = $val['label'];
108  }
109 }
110 
111 // Definition of array of fields for columns
112 $arrayfields = array(
113  'stockqty'=>array('type'=>'float', 'label'=>'PhysicalStock', 'enabled'=>1, 'visible'=>-2, 'checked'=>0, 'position'=>170),
114  'estimatedvalue'=>array('type'=>'float', 'label'=>'EstimatedStockValue', 'enabled'=>1, 'visible'=>1, 'checked'=>1, 'position'=>171),
115  'estimatedstockvaluesell'=>array('type'=>'float', 'label'=>'EstimatedStockValueSell', 'enabled'=>1, 'checked'=>1, 'visible'=>2, 'position'=>172),
116 );
117 foreach ($object->fields as $key => $val) {
118  // If $val['visible']==0, then we never show the field
119  if (!empty($val['visible'])) {
120  $visible = (int) dol_eval($val['visible'], 1, 1, '1');
121  $arrayfields['t.'.$key] = array(
122  'label'=>$val['label'],
123  'checked'=>(($visible < 0) ? 0 : 1),
124  'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')),
125  'position'=>$val['position'],
126  'help'=> isset($val['help']) ? $val['help'] : 'help'
127  );
128  }
129 }
130 // Extra fields
131 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
132 
133 $object->fields = dol_sort_array($object->fields, 'position');
134 $arrayfields = dol_sort_array($arrayfields, 'position');
135 
136 // Security check
137 $result = restrictedArea($user, 'stock');
138 
139 
140 /*
141  * Actions
142  */
143 
144 if (GETPOST('cancel', 'alpha')) {
145  $action = 'list'; $massaction = '';
146 }
147 if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
148  $massaction = '';
149 }
150 
151 $parameters = array();
152 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
153 if ($reshook < 0) {
154  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
155 }
156 
157 if (empty($reshook)) {
158  // Selection of new fields
159  include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
160 
161  // Purge search criteria
162  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
163  foreach ($object->fields as $key => $val) {
164  $search[$key] = '';
165  }
166  $toselect = array();
167  $search_array_options = array();
168  $search_category_list = array();
169  }
170  if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
171  || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
172  $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
173  }
174 
175  // Mass actions
176  $objectclass = 'Entrepot';
177  $objectlabel = 'Warehouse';
178  $permissiontoread = $user->rights->stock->lire;
179  $permissiontodelete = $user->rights->stock->supprimer;
180  $permissiontoadd = $user->rights->stock->creer;
181  $uploaddir = $conf->stock->dir_output;
182  include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
183 }
184 
185 
186 /*
187  * View
188  */
189 
190 $form = new Form($db);
191 $warehouse = new Entrepot($db);
192 
193 $now = dol_now();
194 
195 $help_url = 'EN:Module_Stocks_En|FR:Module_Stock|ES:M&oacute;dulo_Stocks';
196 $title = $langs->trans("ListOfWarehouses");
197 
198 $totalarray = array();
199 $totalarray['nbfield'] = 0;
200 
201 // Build and execute select
202 // --------------------------------------------------------------------
203 $sql = 'SELECT ';
204 foreach ($object->fields as $key => $val) {
205  $sql .= "t.".$key.", ";
206 }
207 // Add fields from extrafields
208 if (!empty($extrafields->attributes[$object->table_element]['label'])) {
209  foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
210  $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key." as options_".$key.', ' : '');
211  }
212 }
213 
214 //For Multicompany PMP per entity
215 $separatedPMP = false;
216 if (!empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED) && !empty($conf->global->MULTICOMPANY_PMP_PER_ENTITY_ENABLED)) {
217  $separatedPMP = true;
218  $sql .= " SUM(pa.pmp * ps.reel) as estimatedvalue, SUM(p.price * ps.reel) as sellvalue, SUM(ps.reel) as stockqty";
219 } else {
220  $sql .= " SUM(p.pmp * ps.reel) as estimatedvalue, SUM(p.price * ps.reel) as sellvalue, SUM(ps.reel) as stockqty";
221 }
222 
223 // Add fields from hooks
224 $parameters = array();
225 $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
226 $sql .= $hookmanager->resPrint;
227 $sql = preg_replace('/,\s*$/', '', $sql);
228 $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
229 if (!empty($conf->categorie->enabled)) {
230  $sql .= Categorie::getFilterJoinQuery(Categorie::TYPE_WAREHOUSE, "t.rowid");
231 }
232 if (!empty($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
233  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)";
234 }
235 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_stock as ps ON t.rowid = ps.fk_entrepot";
236 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON ps.fk_product = p.rowid";
237 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as c_dep ON c_dep.rowid = t.fk_departement";
238 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as ccount ON ccount.rowid = t.fk_pays";
239 if ($separatedPMP) {
240  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_perentity as pa ON pa.fk_product = p.rowid AND pa.fk_product = ps.fk_product AND pa.entity = ". (int) $conf->entity;
241 }
242 
243 $sql .= " WHERE t.entity IN (".getEntity('stock').")";
244 
245 if (!empty($conf->categorie->enabled)) {
246  $sql .= Categorie::getFilterSelectQuery(Categorie::TYPE_WAREHOUSE, "t.rowid", $search_category_list);
247 }
248 foreach ($search as $key => $val) {
249  $class_key = $key;
250  if ($class_key == 'status') {
251  $class_key = 'statut'; // remove this after refactoring entrepot.class property statut to status
252  }
253  if (($key == 'status' && $search[$key] == -1) || $key == 'entity') {
254  continue;
255  }
256  $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0);
257  if (strpos($object->fields[$key]['type'], 'integer:') === 0) {
258  if ($search[$key] == '-1') {
259  $search[$key] = '';
260  }
261  $mode_search = 2;
262  }
263  if ($search[$key] != '') {
264  $sql .= natural_search((($key == "ref") ? "t.ref" : "t.".$class_key), $search[$key], (($key == 'status') ? 2 : $mode_search));
265  }
266 }
267 if ($search_all) {
268  $sql .= natural_search(array_keys($fieldstosearchall), $search_all);
269 }
270 // Add where from extra fields
271 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
272 // Add where from hooks
273 $parameters = array();
274 $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook
275 $sql .= $hookmanager->resPrint;
276 $sql .= " GROUP BY ";
277 foreach ($object->fields as $key => $val) {
278  $sql .= "t.".$key.", ";
279 }
280 // Add fields from extrafields
281 if (!empty($extrafields->attributes[$object->table_element]['label'])) {
282  foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
283  $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : '');
284  }
285 }
286 // Add where from hooks
287 $parameters = array();
288 $reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters); // Note that $action and $object may have been modified by hook
289 $sql .= $hookmanager->resPrint;
290 $sql = preg_replace('/,\s*$/', '', $sql);
291 $totalnboflines = 0;
292 
293 $result = $db->query($sql);
294 if ($result) {
295  $totalnboflines = $db->num_rows($result);
296  // fetch totals
297  $line = $total = $totalsell = $totalStock = 0;
298  while ($line < $totalnboflines) {
299  $objp = $db->fetch_object($result);
300  $total += $objp->estimatedvalue;
301  $totalsell += $objp->sellvalue;
302  $totalStock += $objp->stockqty;
303  $line++;
304  }
305  $totalarray['val']['stockqty'] = price2num($totalStock, 'MS');
306  $totalarray['val']['estimatedvalue'] = price2num($total, 'MT');
307  $totalarray['val']['estimatedstockvaluesell'] = price2num($totalsell, 'MT');
308 }
309 $sql .= $db->order($sortfield, $sortorder);
310 
311 // Count total nb of records
312 $nbtotalofrecords = '';
313 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
314  $resql = $db->query($sql);
315  $nbtotalofrecords = $db->num_rows($resql);
316  if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0
317  $page = 0;
318  $offset = 0;
319  }
320 }
321 // if total of record found is smaller than limit, no need to do paging and to restart another select with limits set.
322 if (is_numeric($nbtotalofrecords) && ($limit > $nbtotalofrecords || empty($limit))) {
323  $num = $nbtotalofrecords;
324 } else {
325  if ($limit) {
326  $sql .= $db->plimit($limit + 1, $offset);
327  }
328 
329  $resql = $db->query($sql);
330  if (!$resql) {
331  dol_print_error($db);
332  exit;
333  }
334 
335  $num = $db->num_rows($resql);
336 }
337 
338 // Direct jump if only one record found
339 if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) {
340  $obj = $db->fetch_object($resql);
341  $id = $obj->rowid;
342  header("Location: ".DOL_URL_ROOT.'/product/stock/card.php?id='.$id);
343  exit;
344 }
345 
346 
347 // Output page
348 // --------------------------------------------------------------------
349 
350 llxHeader('', $title, $help_url);
351 
352 $arrayofselected = is_array($toselect) ? $toselect : array();
353 
354 $param = '';
355 if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
356  $param .= '&contextpage='.urlencode($contextpage);
357 }
358 if ($limit > 0 && $limit != $conf->liste_limit) {
359  $param .= '&limit='.urlencode($limit);
360 }
361 foreach ($search as $key => $val) {
362  if (is_array($search[$key]) && count($search[$key])) {
363  foreach ($search[$key] as $skey) {
364  $param .= '&search_'.$key.'[]='.urlencode($skey);
365  }
366  } else {
367  $param .= '&search_'.$key.'='.urlencode($search[$key]);
368  }
369 }
370 if ($optioncss != '') {
371  $param .= '&optioncss='.urlencode($optioncss);
372 }
373 // Add $param from extra fields
374 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
375 
376 // List of mass actions available
377 $arrayofmassactions = array(
378  //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
379  //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
380 );
381 //if ($user->rights->stock->supprimer) $arrayofmassactions['predelete']=img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
382 if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete','preaffecttag'))) {
383  $arrayofmassactions = array();
384 }
385 if (isModEnabled('category') && $user->rights->stock->creer) {
386  $arrayofmassactions['preaffecttag'] = img_picto('', 'label', 'class="pictofixedwidth"').$langs->trans("AffectTag");
387 }
388 $massactionbutton = $form->selectMassAction('', $arrayofmassactions);
389 
390 print '<form action="'.$_SERVER["PHP_SELF"].'" id="searchFormList" method="POST" name="formulaire">';
391 if ($optioncss != '') {
392  print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
393 }
394 print '<input type="hidden" name="token" value="'.newToken().'">';
395 print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
396 print '<input type="hidden" name="action" value="list">';
397 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
398 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
399 print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
400 
401 $newcardbutton = dolGetButtonTitle($langs->trans('MenuNewWarehouse'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/product/stock/card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $user->rights->stock->creer);
402 
403 print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'stock', 0, $newcardbutton, '', $limit, 0, 0, 1);
404 
405 // Add code for pre mass action (confirmation or email presend form)
406 $topicmail = "Information";
407 $modelmail = "warehouse";
408 $objecttmp = new Entrepot($db);
409 $trackid = 'ware'.$object->id;
410 include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
411 
412 
413 if ($search_all) {
414  foreach ($fieldstosearchall as $key => $val) {
415  $fieldstosearchall[$key] = $langs->trans($val);
416  }
417  print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $sall).join(', ', $fieldstosearchall).'</div>';
418 }
419 
420 $moreforfilter = '';
421 
422 if (!empty($conf->categorie->enabled) && $user->rights->categorie->lire) {
423  $formcategory = new FormCategory($db);
424  $moreforfilter .= $formcategory->getFilterBox(Categorie::TYPE_WAREHOUSE, $search_category_list);
425 }
426 
427 /*$moreforfilter.='<div class="divsearchfield">';
428  $moreforfilter.= $langs->trans('MyFilter') . ': <input type="text" name="search_myfield" value="'.dol_escape_htmltag($search_myfield).'">';
429  $moreforfilter.= '</div>';*/
430 
431 $parameters = array();
432 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
433 if (empty($reshook)) {
434  $moreforfilter .= $hookmanager->resPrint;
435 } else {
436  $moreforfilter = $hookmanager->resPrint;
437 }
438 
439 if (!empty($moreforfilter)) {
440  print '<div class="liste_titre liste_titre_bydiv centpercent">';
441  print $moreforfilter;
442  print '</div>';
443 }
444 
445 $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
446 $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
447 $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
448 
449 print '<div class="div-table-responsive">';
450 print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
451 
452 // Fields title search
453 // --------------------------------------------------------------------
454 print '<tr class="liste_titre_filter">';
455 
456 foreach ($object->fields as $key => $val) {
457  if ($key == 'statut') {
458  continue;
459  }
460  $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
461  if ($key == 'status') {
462  $cssforfield .= ($cssforfield ? ' ' : '').'center';
463  } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
464  $cssforfield .= ($cssforfield ? ' ' : '').'center';
465  } elseif (in_array($val['type'], array('timestamp'))) {
466  $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
467  } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) {
468  $cssforfield .= ($cssforfield ? ' ' : '').'right';
469  }
470  if (!empty($arrayfields['t.'.$key]['checked'])) {
471  print '<td class="liste_titre'.($cssforfield ? ' '.$cssforfield : '').'">';
472  if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
473  print $form->selectarray('search_'.$key, $val['arrayofkeyval'], $search[$key], $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1);
474  } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) {
475  print $object->showInputField($val, $key, $search[$key], '', '', 'search_', 'maxwidth125', 1);
476  } elseif (!preg_match('/^(date|timestamp)/', $val['type'])) {
477  print '<input type="text" class="flat maxwidth75" name="search_'.$key.'" value="'.dol_escape_htmltag(!empty($search[$key])?$search[$key]:'').'">';
478  }
479  print '</td>';
480  }
481 }
482 
483 if (!empty($arrayfields["stockqty"]['checked'])) {
484  print '<td class="liste_titre"></td>';
485 }
486 
487 if (!empty($arrayfields["estimatedvalue"]['checked'])) {
488  print '<td class="liste_titre"></td>';
489 }
490 
491 if (!empty($arrayfields["estimatedstockvaluesell"]['checked'])) {
492  print '<td class="liste_titre"></td>';
493 }
494 
495 // Extra fields
496 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
497 
498 // Fields from hook
499 $parameters = array('arrayfields'=>$arrayfields);
500 $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook
501 print $hookmanager->resPrint;
502 
503 // Status
504 if (!empty($arrayfields['t.statut']['checked'])) {
505  print '<td class="liste_titre center">';
506  print $form->selectarray('search_status', $warehouse->statuts, $search_status, 1, 0, 0, '', 1);
507  print '</td>';
508 }
509 
510 // Action column
511 print '<td class="liste_titre maxwidthsearch">';
512 $searchpicto = $form->showFilterButtons();
513 print $searchpicto;
514 print '</td>';
515 print '</tr>'."\n";
516 
517 // Fields title label
518 // --------------------------------------------------------------------
519 print '<tr class="liste_titre">';
520 
521 foreach ($object->fields as $key => $val) {
522  if ($key == 'statut') {
523  continue;
524  }
525  $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
526  if ($key == 'status') {
527  $cssforfield .= ($cssforfield ? ' ' : '').'center';
528  } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
529  $cssforfield .= ($cssforfield ? ' ' : '').'center';
530  } elseif (in_array($val['type'], array('timestamp'))) {
531  $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
532  } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) {
533  $cssforfield .= ($cssforfield ? ' ' : '').'right';
534  }
535  if (!empty($arrayfields['t.'.$key]['checked'])) {
536  print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''))."\n";
537  }
538 }
539 
540 if (!empty($arrayfields["stockqty"]['checked'])) {
541  print_liste_field_titre("PhysicalStock", $_SERVER["PHP_SELF"], "stockqty", '', $param, '', $sortfield, $sortorder, 'right ');
542 }
543 
544 if (!empty($arrayfields["estimatedvalue"]['checked'])) {
545  print_liste_field_titre("EstimatedStockValue", $_SERVER["PHP_SELF"], "estimatedvalue", '', $param, '', $sortfield, $sortorder, 'right ');
546 }
547 
548 if (!empty($arrayfields["estimatedstockvaluesell"]['checked'])) {
549  print_liste_field_titre("EstimatedStockValueSell", $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ');
550 }
551 
552 // Extra fields
553 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
554 
555 // Hook fields
556 $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder);
557 $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
558 print $hookmanager->resPrint;
559 
560 if (!empty($arrayfields['t.statut']['checked'])) {
561  print_liste_field_titre($arrayfields['t.statut']['label'], $_SERVER["PHP_SELF"], "t.statut", '', $param, '', $sortfield, $sortorder, 'center ');
562 }
563 
564 // Action column
565 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
566 print '</tr>'."\n";
567 
568 // Loop on record
569 // --------------------------------------------------------------------
570 $i = 0;
571 
572 $warehouse = new Entrepot($db);
573 
574 while ($i < min($num, $limit)) {
575  $obj = $db->fetch_object($resql);
576  if (empty($obj)) {
577  break; // Should not happen
578  }
579 
580  // Store properties in $object
581  $warehouse->setVarsFromFetchObj($obj);
582 
583  $warehouse->label = $warehouse->ref;
584 
585  // Show here line of result
586  print '<tr class="oddeven">';
587 
588  foreach ($warehouse->fields as $key => $val) {
589  if ($key == 'statut') {
590  continue;
591  }
592  $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
593  if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
594  $cssforfield .= ($cssforfield ? ' ' : '').'center';
595  } elseif ($key == 'status') {
596  $cssforfield .= ($cssforfield ? ' ' : '').'center';
597  }
598 
599  if (in_array($val['type'], array('timestamp'))) {
600  $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
601  } elseif ($key == 'ref') {
602  $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
603  }
604 
605  if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $key != 'status' && empty($val['arrayofkeyval'])) {
606  $cssforfield .= ($cssforfield ? ' ' : '').'right';
607  }
608  if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) {
609  $cssforfield = 'tdoverflowmax100';
610  }
611 
612  if (!empty($arrayfields['t.'.$key]['checked'])) {
613  print '<td'.($cssforfield ? ' class="'.$cssforfield.'"' : '').'>';
614  if ($key == 'statut') {
615  print $warehouse->getLibStatut(5);
616  }
617  if ($key == 'phone') {
618  print dol_print_phone($obj->phone, '', 0, $obj->rowid, 'AC_TEL');
619  } elseif ($key == 'fax') {
620  print dol_print_phone($obj->fax, '', 0, $obj->rowid, 'AC_FAX');
621  } else {
622  print $warehouse->showOutputField($val, $key, $warehouse->$key, '');
623  }
624  print '</td>';
625  if (!$i) {
626  $totalarray['nbfield']++;
627  }
628  if (!empty($val['isameasure']) && $val['isameasure'] == 1) {
629  if (!$i) {
630  $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key;
631  }
632  if (!isset($totalarray['val'])) {
633  $totalarray['val'] = array();
634  }
635  if (!isset($totalarray['val']['t.'.$key])) {
636  $totalarray['val']['t.'.$key] = 0;
637  }
638  $totalarray['val']['t.'.$key] += $warehouse->$key;
639  }
640  }
641  }
642 
643  // Stock qty
644  if (!empty($arrayfields["stockqty"]['checked'])) {
645  print '<td class="right">'.price2num($obj->stockqty, 5).'</td>';
646  if (!$i) {
647  $totalarray['nbfield']++;
648  }
649  if (!$i) {
650  $totalarray['pos'][$totalarray['nbfield']] = 'stockqty';
651  }
652  }
653 
654  // PMP value
655  if (!empty($arrayfields["estimatedvalue"]['checked'])) {
656  print '<td class="right">';
657  if (price2num($obj->estimatedvalue, 'MT')) {
658  print '<span class="amount">'.price(price2num($obj->estimatedvalue, 'MT'), 1).'</span>';
659  } else {
660  print '';
661  }
662  print '</td>';
663  if (!$i) {
664  $totalarray['nbfield']++;
665  }
666  if (!$i) {
667  $totalarray['pos'][$totalarray['nbfield']] = 'estimatedvalue';
668  }
669  }
670 
671  // Selling value
672  if (!empty($arrayfields["estimatedstockvaluesell"]['checked'])) {
673  print '<td class="right">';
674  if (empty($conf->global->PRODUIT_MULTIPRICES)) {
675  if ($obj->sellvalue) {
676  print '<span class="amount">'.price(price2num($obj->sellvalue, 'MT'), 1).'</span>';
677  }
678  } else {
679  $htmltext = $langs->trans("OptionMULTIPRICESIsOn");
680  print $form->textwithtooltip('<span class="opacitymedium">'.$langs->trans("Variable").'</span>', $htmltext);
681  }
682  print '</td>';
683  if (!$i) {
684  $totalarray['nbfield']++;
685  }
686  if (!$i) {
687  $totalarray['pos'][$totalarray['nbfield']] = 'estimatedstockvaluesell';
688  }
689  }
690 
691  // Extra fields
692  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
693  // Fields from hook
694  $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray);
695  $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook
696  print $hookmanager->resPrint;
697 
698  // Status
699  if (!empty($arrayfields['t.statut']['checked'])) {
700  print '<td class="center">'.$warehouse->LibStatut($obj->statut, 5).'</td>';
701  if (!$i) {
702  $totalarray['nbfield']++;
703  }
704  }
705 
706  // Action column
707  print '<td class="nowrap center">';
708  if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
709  $selected = 0;
710  if (in_array($obj->rowid, $arrayofselected)) {
711  $selected = 1;
712  }
713  print '<input id="cb'.$obj->rowid.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected ? ' checked="checked"' : '').'>';
714  }
715  print '</td>';
716  if (!$i) {
717  $totalarray['nbfield']++;
718  }
719 
720  print '</tr>'."\n";
721 
722 
723  $i++;
724 }
725 
726 if ($totalnboflines - $offset <= $limit) {
727  // Show total line
728  include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
729 }
730 
731 // If no record found
732 if ($num == 0) {
733  $colspan = 1;
734  foreach ($arrayfields as $key => $val) {
735  if (!empty($val['checked'])) {
736  $colspan++;
737  }
738  }
739  print '<tr><td colspan="'.$colspan.'" class="opacitymedium">'.$langs->trans("NoRecordFound").'</td></tr>';
740 }
741 
742 $db->free($resql);
743 
744 $parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql);
745 $reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object); // Note that $action and $object may have been modified by hook
746 print $hookmanager->resPrint;
747 
748 print '</table>'."\n";
749 print '</div>'."\n";
750 
751 print '</form>'."\n";
752 
753 if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
754  $hidegeneratedfilelistifempty = 1;
755  if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
756  $hidegeneratedfilelistifempty = 0;
757  }
758 
759  require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
760  $formfile = new FormFile($db);
761 
762  // Show list of available documents
763  $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
764  $urlsource .= str_replace('&amp;', '&', $param);
765 
766  $filedir = $diroutputmassaction;
767  $genallowed = $user->rights->stock->lire;
768  $delallowed = $user->rights->stock->creer;
769 
770  print $formfile->showdocuments('massfilesarea_stock', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
771 }
772 
773 // End of page
774 llxFooter();
775 $db->close();
dol_escape_htmltag
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.
Definition: functions.lib.php:1468
restrictedArea
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.
Definition: security.lib.php:234
llxFooter
llxFooter()
Empty footer.
Definition: wrapper.php:73
getTitleFieldOfList
getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $disablesortlink=0, $tooltip='', $forcenowrapcolumntitle=0)
Get title line of an array.
Definition: functions.lib.php:5049
GETPOST
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
Definition: functions.lib.php:484
dol_print_error
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
Definition: functions.lib.php:4844
dol_sort_array
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by second index function, which produces ascending (default) or descending output...
Definition: functions.lib.php:8385
FormCategory
Class to manage forms for categories.
Definition: html.formcategory.class.php:30
$form
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:142
$help_url
if(GETPOST('button_removefilter_x', 'alpha')||GETPOST('button_removefilter.x', 'alpha')||GETPOST('button_removefilter', 'alpha')) if(GETPOST('button_search_x', 'alpha')||GETPOST('button_search.x', 'alpha')||GETPOST('button_search', 'alpha')) if($action=="save" &&empty($cancel)) $help_url
View.
Definition: agenda.php:116
price2num
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
Definition: functions.lib.php:5661
img_picto
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
Definition: functions.lib.php:3880
FormFile
Class to offer components to list and upload files.
Definition: html.formfile.class.php:36
Categorie\getFilterSelectQuery
static getFilterSelectQuery($type, $rowIdName, $searchList)
Return the addtional SQL SELECT query for filtering a list by a category.
Definition: categorie.class.php:2001
dolGetButtonTitle
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
Definition: functions.lib.php:10605
print_barre_liste
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.
Definition: functions.lib.php:5257
isModEnabled
isModEnabled($module)
Is Dolibarr module enabled.
Definition: functions.lib.php:105
GETPOSTISSET
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
Definition: functions.lib.php:386
print_liste_field_titre
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
Definition: functions.lib.php:5026
natural_search
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...
Definition: functions.lib.php:9420
dol_eval
dol_eval($s, $returnvalue=0, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
Definition: functions.lib.php:8611
ExtraFields
Class to manage standard extra fields.
Definition: extrafields.class.php:39
Form
Class to manage generation of HTML components Only common components must be here.
Definition: html.form.class.php:52
Entrepot
Class to manage warehouses.
Definition: entrepot.class.php:35
dol_now
dol_now($mode='auto')
Return date for now.
Definition: functions.lib.php:2845
$resql
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_phone
dol_print_phone($phone, $countrycode='', $cid=0, $socid=0, $addlink='', $separ="&nbsp;", $withpicto='', $titlealt='', $adddivfloat=0)
Format phone numbers according to country.
Definition: functions.lib.php:3185
setEventMessages
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
Definition: functions.lib.php:8137
llxHeader
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
Categorie\getFilterJoinQuery
static getFilterJoinQuery($type, $rowIdName)
Return the addtional SQL JOIN query for filtering a list by a category.
Definition: categorie.class.php:1984