dolibarr  x.y.z
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 // Load Dolibarr environment
29 require '../../main.inc.php';
30 require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
31 
32 if (isModEnabled('categorie')) {
33  require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcategory.class.php';
34  require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
35 }
36 
37 // Load translation files required by the page
38 $langs->loadLangs(array("stocks", "other"));
39 
40 $action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ...
41 $massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
42 $show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk actions ?
43 $confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation
44 $cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button
45 $toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list
46 $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'stocklist'; // To manage different context of search
47 $backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
48 $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
49 $toselect = GETPOST('toselect', 'array');
50 
51 
52 $search_all = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'));
53 $search_ref = GETPOST("sref", "alpha") ?GETPOST("sref", "alpha") : GETPOST("search_ref", "alpha");
54 $search_label = GETPOST("snom", "alpha") ?GETPOST("snom", "alpha") : GETPOST("search_label", "alpha");
55 $search_status = GETPOST("search_status", "int");
56 $mode = GETPOST('mode', 'alpha');
57 
58 
59 if (isModEnabled('categorie')) {
60  $search_category_list = GETPOST("search_category_".Categorie::TYPE_WAREHOUSE."_list", "array");
61 }
62 
63 // Load variable for pagination
64 $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
65 $sortfield = GETPOST('sortfield', 'aZ09comma');
66 $sortorder = GETPOST('sortorder', 'aZ09comma');
67 $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
68 if (empty($page) || $page == -1 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) {
69  $page = 0;
70 } // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action
71 $offset = $limit * $page;
72 $pageprev = $page - 1;
73 $pagenext = $page + 1;
74 if (!$sortfield) {
75  $sortfield = "t.ref";
76 }
77 if (!$sortorder) {
78  $sortorder = "ASC";
79 }
80 
81 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
82 $object = new Entrepot($db);
83 $extrafields = new ExtraFields($db);
84 $diroutputmassaction = $conf->stock->dir_output.'/temp/massgeneration/'.$user->id;
85 $hookmanager->initHooks(array('stocklist'));
86 
87 // Fetch optionals attributes and labels
88 $extrafields->fetch_name_optionals_label($object->table_element);
89 
90 $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
91 
92 
93 // Initialize array of search criterias
94 $search_all = GETPOST("search_all", 'alpha');
95 $search = array();
96 foreach ($object->fields as $key => $val) {
97  $search_key = $key;
98  if ($search_key == 'statut') {
99  $search_key = 'status'; // remove this after refactor entrepot.class property statut to status
100  }
101  if (GETPOST('search_'.$search_key, 'alpha') !== '') {
102  $search[$search_key] = GETPOST('search_'.$search_key, 'alpha');
103  }
104 }
105 
106 // List of fields to search into when doing a "search in all"
107 $fieldstosearchall = array();
108 foreach ($object->fields as $key => $val) {
109  if (!empty($val['searchall'])) {
110  $fieldstosearchall['t.'.$key] = $val['label'];
111  }
112 }
113 
114 // Definition of array of fields for columns
115 $arrayfields = array(
116  'stockqty'=>array('type'=>'float', 'label'=>'PhysicalStock', 'enabled'=>1, 'visible'=>-2, 'checked'=>0, 'position'=>170),
117  'estimatedvalue'=>array('type'=>'float', 'label'=>'EstimatedStockValue', 'enabled'=>1, 'visible'=>1, 'checked'=>1, 'position'=>171),
118  'estimatedstockvaluesell'=>array('type'=>'float', 'label'=>'EstimatedStockValueSell', 'enabled'=>1, 'checked'=>1, 'visible'=>2, 'position'=>172),
119 );
120 foreach ($object->fields as $key => $val) {
121  // If $val['visible']==0, then we never show the field
122  if (!empty($val['visible'])) {
123  $visible = (int) dol_eval($val['visible'], 1, 1, '1');
124  $arrayfields['t.'.$key] = array(
125  'label'=>$val['label'],
126  'checked'=>(($visible < 0) ? 0 : 1),
127  'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')),
128  'position'=>$val['position'],
129  'help'=> isset($val['help']) ? $val['help'] : 'help'
130  );
131  }
132 }
133 // Extra fields
134 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
135 
136 $object->fields = dol_sort_array($object->fields, 'position');
137 $arrayfields = dol_sort_array($arrayfields, 'position');
138 
139 // Security check
140 $result = restrictedArea($user, 'stock');
141 
142 
143 /*
144  * Actions
145  */
146 
147 if (GETPOST('cancel', 'alpha')) {
148  $action = 'list'; $massaction = '';
149 }
150 if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
151  $massaction = '';
152 }
153 
154 $parameters = array();
155 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
156 if ($reshook < 0) {
157  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
158 }
159 
160 if (empty($reshook)) {
161  // Selection of new fields
162  include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
163 
164  // Purge search criteria
165  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
166  foreach ($object->fields as $key => $val) {
167  $search[$key] = '';
168  }
169  $toselect = array();
170  $search_array_options = array();
171  $search_category_list = array();
172  }
173  if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
174  || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
175  $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
176  }
177 
178  // Mass actions
179  $objectclass = 'Entrepot';
180  $objectlabel = 'Warehouse';
181  $permissiontoread = $user->rights->stock->lire;
182  $permissiontodelete = $user->rights->stock->supprimer;
183  $permissiontoadd = $user->rights->stock->creer;
184  $uploaddir = $conf->stock->dir_output;
185  include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
186 }
187 
188 
189 /*
190  * View
191  */
192 
193 $form = new Form($db);
194 $warehouse = new Entrepot($db);
195 
196 $now = dol_now();
197 
198 $help_url = 'EN:Module_Stocks_En|FR:Module_Stock|ES:M&oacute;dulo_Stocks';
199 $title = $langs->trans("Warehouses");
200 
201 $totalarray = array();
202 $totalarray['nbfield'] = 0;
203 
204 // Build and execute select
205 // --------------------------------------------------------------------
206 $sql = 'SELECT ';
207 foreach ($object->fields as $key => $val) {
208  $sql .= "t.".$key.", ";
209 }
210 // Add fields from extrafields
211 if (!empty($extrafields->attributes[$object->table_element]['label'])) {
212  foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
213  $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key." as options_".$key.', ' : '');
214  }
215 }
216 
217 //For Multicompany PMP per entity
218 $separatedPMP = false;
219 if (!empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED) && !empty($conf->global->MULTICOMPANY_PMP_PER_ENTITY_ENABLED)) {
220  $separatedPMP = true;
221  $sql .= " SUM(pa.pmp * ps.reel) as estimatedvalue, SUM(p.price * ps.reel) as sellvalue, SUM(ps.reel) as stockqty";
222 } else {
223  $sql .= " SUM(p.pmp * ps.reel) as estimatedvalue, SUM(p.price * ps.reel) as sellvalue, SUM(ps.reel) as stockqty";
224 }
225 
226 // Add fields from hooks
227 $parameters = array();
228 $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
229 $sql .= $hookmanager->resPrint;
230 $sql = preg_replace('/,\s*$/', '', $sql);
231 $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
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 $sql .= " WHERE t.entity IN (".getEntity('stock').")";
243 foreach ($search as $key => $val) {
244  $class_key = $key;
245  if ($class_key == 'status') {
246  $class_key = 'statut'; // remove this after refactoring entrepot.class property statut to status
247  }
248  if (($key == 'status' && $search[$key] == -1) || $key == 'entity') {
249  continue;
250  }
251  $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0);
252  if (strpos($object->fields[$key]['type'], 'integer:') === 0) {
253  if ($search[$key] == '-1') {
254  $search[$key] = '';
255  }
256  $mode_search = 2;
257  }
258  if ($search[$key] != '') {
259  $sql .= natural_search((($key == "ref") ? "t.ref" : "t.".$class_key), $search[$key], (($key == 'status') ? 2 : $mode_search));
260  }
261 }
262 if ($search_all) {
263  $sql .= natural_search(array_keys($fieldstosearchall), $search_all);
264 }
265 // Search for tag/category ($searchCategoryWarehouseList is an array of ID)
266 $searchCategoryWarehouseList = $search_category_list;
267 $searchCategoryWarehouseOperator = 0;
268 if (!empty($searchCategoryWarehouseList)) {
269  $searchCategoryWarehouseSqlList = array();
270  $listofcategoryid = '';
271  foreach ($searchCategoryWarehouseList as $searchCategoryWarehouse) {
272  if (intval($searchCategoryWarehouse) == -2) {
273  $searchCategoryWarehouseSqlList[] = "NOT EXISTS (SELECT ck.fk_warehouse FROM ".MAIN_DB_PREFIX."categorie_warehouse as ck WHERE p.rowid = ck.fk_warehouse)";
274  } elseif (intval($searchCategoryWarehouse) > 0) {
275  if ($searchCategoryWarehouseOperator == 0) {
276  $searchCategoryWarehouseSqlList[] = " EXISTS (SELECT ck.fk_warehouse FROM ".MAIN_DB_PREFIX."categorie_warehouse as ck WHERE p.rowid = ck.fk_warehouse AND ck.fk_categorie = ".((int) $searchCategoryWarehouse).")";
277  } else {
278  $listofcategoryid .= ($listofcategoryid ? ', ' : '') .((int) $searchCategoryWarehouse);
279  }
280  }
281  }
282  if ($listofcategoryid) {
283  $searchCategoryWarehouseSqlList[] = " EXISTS (SELECT ck.fk_warehouse FROM ".MAIN_DB_PREFIX."categorie_warehouse as ck WHERE p.rowid = ck.fk_warehouse AND ck.fk_categorie IN (".$db->sanitize($listofcategoryid)."))";
284  }
285  if ($searchCategoryWarehouseOperator == 1) {
286  if (!empty($searchCategoryWarehouseSqlList)) {
287  $sql .= " AND (".implode(' OR ', $searchCategoryWarehouseSqlList).")";
288  }
289  } else {
290  if (!empty($searchCategoryWarehouseSqlList)) {
291  $sql .= " AND (".implode(' AND ', $searchCategoryWarehouseSqlList).")";
292  }
293  }
294 }
295 
296 // Add where from extra fields
297 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
298 // Add where from hooks
299 $parameters = array();
300 $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook
301 $sql .= $hookmanager->resPrint;
302 $sql .= " GROUP BY ";
303 foreach ($object->fields as $key => $val) {
304  $sql .= "t.".$key.", ";
305 }
306 // Add fields from extrafields
307 if (!empty($extrafields->attributes[$object->table_element]['label'])) {
308  foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
309  $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : '');
310  }
311 }
312 // Add where from hooks
313 $parameters = array();
314 $reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters); // Note that $action and $object may have been modified by hook
315 $sql .= $hookmanager->resPrint;
316 $sql = preg_replace('/,\s*$/', '', $sql);
317 $totalnboflines = 0;
318 
319 $result = $db->query($sql);
320 if ($result) {
321  $totalnboflines = $db->num_rows($result);
322  // fetch totals
323  $line = $total = $totalsell = $totalStock = 0;
324  while ($line < $totalnboflines) {
325  $objp = $db->fetch_object($result);
326  $total += $objp->estimatedvalue;
327  $totalsell += $objp->sellvalue;
328  $totalStock += $objp->stockqty;
329  $line++;
330  }
331  $totalarray['val']['stockqty'] = price2num($totalStock, 'MS');
332  $totalarray['val']['estimatedvalue'] = price2num($total, 'MT');
333  $totalarray['val']['estimatedstockvaluesell'] = price2num($totalsell, 'MT');
334 }
335 $sql .= $db->order($sortfield, $sortorder);
336 
337 // Count total nb of records
338 $nbtotalofrecords = '';
339 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
340  $resql = $db->query($sql);
341  $nbtotalofrecords = $db->num_rows($resql);
342  if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0
343  $page = 0;
344  $offset = 0;
345  }
346 }
347 // if total of record found is smaller than limit, no need to do paging and to restart another select with limits set.
348 if (is_numeric($nbtotalofrecords) && ($limit > $nbtotalofrecords || empty($limit))) {
349  $num = $nbtotalofrecords;
350 } else {
351  if ($limit) {
352  $sql .= $db->plimit($limit + 1, $offset);
353  }
354 
355  $resql = $db->query($sql);
356  if (!$resql) {
357  dol_print_error($db);
358  exit;
359  }
360 
361  $num = $db->num_rows($resql);
362 }
363 
364 // Direct jump if only one record found
365 if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) {
366  $obj = $db->fetch_object($resql);
367  $id = $obj->rowid;
368  header("Location: ".DOL_URL_ROOT.'/product/stock/card.php?id='.$id);
369  exit;
370 }
371 
372 
373 // Output page
374 // --------------------------------------------------------------------
375 
376 llxHeader('', $title, $help_url);
377 
378 $arrayofselected = is_array($toselect) ? $toselect : array();
379 
380 $param = '';
381 if (!empty($mode)) {
382  $param .= '&mode='.urlencode($mode);
383 }
384 if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
385  $param .= '&contextpage='.urlencode($contextpage);
386 }
387 if ($limit > 0 && $limit != $conf->liste_limit) {
388  $param .= '&limit='.urlencode($limit);
389 }
390 foreach ($search as $key => $val) {
391  if (is_array($search[$key]) && count($search[$key])) {
392  foreach ($search[$key] as $skey) {
393  $param .= '&search_'.$key.'[]='.urlencode($skey);
394  }
395  } else {
396  $param .= '&search_'.$key.'='.urlencode($search[$key]);
397  }
398 }
399 if ($optioncss != '') {
400  $param .= '&optioncss='.urlencode($optioncss);
401 }
402 // Add $param from extra fields
403 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
404 
405 // List of mass actions available
406 $arrayofmassactions = array(
407  //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
408  //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
409 );
410 //if ($user->rights->stock->supprimer) $arrayofmassactions['predelete']=img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
411 if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete','preaffecttag'))) {
412  $arrayofmassactions = array();
413 }
414 if (isModEnabled('category') && $user->rights->stock->creer) {
415  $arrayofmassactions['preaffecttag'] = img_picto('', 'label', 'class="pictofixedwidth"').$langs->trans("AffectTag");
416 }
417 $massactionbutton = $form->selectMassAction('', $arrayofmassactions);
418 
419 print '<form action="'.$_SERVER["PHP_SELF"].'" id="searchFormList" method="POST" name="formulaire">';
420 if ($optioncss != '') {
421  print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
422 }
423 print '<input type="hidden" name="token" value="'.newToken().'">';
424 print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
425 print '<input type="hidden" name="action" value="list">';
426 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
427 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
428 print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
429 print '<input type="hidden" name="mode" value="'.$mode.'">';
430 
431 
432 $newcardbutton = '';
433 $newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss'=>'reposition'));
434 $newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss'=>'reposition'));
435 $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);
436 
437 print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'stock', 0, $newcardbutton, '', $limit, 0, 0, 1);
438 
439 // Add code for pre mass action (confirmation or email presend form)
440 $topicmail = "Information";
441 $modelmail = "warehouse";
442 $objecttmp = new Entrepot($db);
443 $trackid = 'ware'.$object->id;
444 include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
445 
446 
447 if ($search_all) {
448  foreach ($fieldstosearchall as $key => $val) {
449  $fieldstosearchall[$key] = $langs->trans($val);
450  }
451  print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $sall).join(', ', $fieldstosearchall).'</div>';
452 }
453 
454 $moreforfilter = '';
455 
456 if (isModEnabled('categorie') && $user->rights->categorie->lire) {
457  $formcategory = new FormCategory($db);
458  $moreforfilter .= $formcategory->getFilterBox(Categorie::TYPE_WAREHOUSE, $search_category_list);
459 }
460 
461 /*$moreforfilter.='<div class="divsearchfield">';
462  $moreforfilter.= $langs->trans('MyFilter') . ': <input type="text" name="search_myfield" value="'.dol_escape_htmltag($search_myfield).'">';
463  $moreforfilter.= '</div>';*/
464 
465 $parameters = array();
466 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
467 if (empty($reshook)) {
468  $moreforfilter .= $hookmanager->resPrint;
469 } else {
470  $moreforfilter = $hookmanager->resPrint;
471 }
472 
473 if (!empty($moreforfilter)) {
474  print '<div class="liste_titre liste_titre_bydiv centpercent">';
475  print $moreforfilter;
476  print '</div>';
477 }
478 
479 $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
480 $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // This also change content of $arrayfields
481 $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
482 
483 print '<div class="div-table-responsive">';
484 print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
485 
486 // Fields title search
487 // --------------------------------------------------------------------
488 print '<tr class="liste_titre_filter">';
489 // Action column
490 if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
491  print '<td class="liste_titre maxwidthsearch">';
492  $searchpicto = $form->showFilterButtons('left');
493  print $searchpicto;
494  print '</td>';
495 }
496 foreach ($object->fields as $key => $val) {
497  if ($key == 'statut') {
498  continue;
499  }
500  $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
501  if ($key == 'status') {
502  $cssforfield .= ($cssforfield ? ' ' : '').'center';
503  } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
504  $cssforfield .= ($cssforfield ? ' ' : '').'center';
505  } elseif (in_array($val['type'], array('timestamp'))) {
506  $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
507  } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) {
508  $cssforfield .= ($cssforfield ? ' ' : '').'right';
509  }
510  if (!empty($arrayfields['t.'.$key]['checked'])) {
511  print '<td class="liste_titre'.($cssforfield ? ' '.$cssforfield : '').'">';
512  if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
513  print $form->selectarray('search_'.$key, $val['arrayofkeyval'], $search[$key], $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1);
514  } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) {
515  print $object->showInputField($val, $key, $search[$key], '', '', 'search_', 'maxwidth125', 1);
516  } elseif (!preg_match('/^(date|timestamp)/', $val['type'])) {
517  print '<input type="text" class="flat maxwidth75" name="search_'.$key.'" value="'.dol_escape_htmltag(!empty($search[$key])?$search[$key]:'').'">';
518  }
519  print '</td>';
520  }
521 }
522 
523 if (!empty($arrayfields["stockqty"]['checked'])) {
524  print '<td class="liste_titre"></td>';
525 }
526 
527 if (!empty($arrayfields["estimatedvalue"]['checked'])) {
528  print '<td class="liste_titre"></td>';
529 }
530 
531 if (!empty($arrayfields["estimatedstockvaluesell"]['checked'])) {
532  print '<td class="liste_titre"></td>';
533 }
534 
535 // Extra fields
536 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
537 
538 // Fields from hook
539 $parameters = array('arrayfields'=>$arrayfields);
540 $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook
541 print $hookmanager->resPrint;
542 
543 // Status
544 if (!empty($arrayfields['t.statut']['checked'])) {
545  print '<td class="liste_titre center">';
546  print $form->selectarray('search_status', $warehouse->statuts, $search_status, 1, 0, 0, '', 1, 0, 0, '', 'onrightofpage');
547  print '</td>';
548 }
549 
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 // Fields title label
560 // --------------------------------------------------------------------
561 print '<tr class="liste_titre">';
562 
563 // Action column
564 if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
565  print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
566 }
567 foreach ($object->fields as $key => $val) {
568  if ($key == 'statut') {
569  continue;
570  }
571  $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
572  if ($key == 'status') {
573  $cssforfield .= ($cssforfield ? ' ' : '').'center';
574  } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
575  $cssforfield .= ($cssforfield ? ' ' : '').'center';
576  } elseif (in_array($val['type'], array('timestamp'))) {
577  $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
578  } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) {
579  $cssforfield .= ($cssforfield ? ' ' : '').'right';
580  }
581  if (!empty($arrayfields['t.'.$key]['checked'])) {
582  print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''))."\n";
583  }
584 }
585 
586 if (!empty($arrayfields["stockqty"]['checked'])) {
587  print_liste_field_titre("PhysicalStock", $_SERVER["PHP_SELF"], "stockqty", '', $param, '', $sortfield, $sortorder, 'right ');
588 }
589 
590 if (!empty($arrayfields["estimatedvalue"]['checked'])) {
591  print_liste_field_titre("EstimatedStockValue", $_SERVER["PHP_SELF"], "estimatedvalue", '', $param, '', $sortfield, $sortorder, 'right ');
592 }
593 
594 if (!empty($arrayfields["estimatedstockvaluesell"]['checked'])) {
595  print_liste_field_titre("EstimatedStockValueSell", $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ');
596 }
597 
598 // Extra fields
599 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
600 
601 // Hook fields
602 $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder);
603 $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
604 print $hookmanager->resPrint;
605 
606 if (!empty($arrayfields['t.statut']['checked'])) {
607  print_liste_field_titre($arrayfields['t.statut']['label'], $_SERVER["PHP_SELF"], "t.statut", '', $param, '', $sortfield, $sortorder, 'center ');
608 }
609 
610 // Action column
611 if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
612  print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
613 }
614 print '</tr>'."\n";
615 
616 // Loop on record
617 // --------------------------------------------------------------------
618 $i = 0;
619 
620 $warehouse = new Entrepot($db);
621 
622 while ($i < min($num, $limit)) {
623  $obj = $db->fetch_object($resql);
624  if (empty($obj)) {
625  break; // Should not happen
626  }
627 
628  // Store properties in $object
629  $warehouse->setVarsFromFetchObj($obj);
630 
631  $warehouse->label = $warehouse->ref;
632  $warehouse->sellvalue = $obj->sellvalue;
633 
634  if ($mode =='kanban') {
635  if ($i == 0) {
636  print '<tr><td colspan="12">';
637  print '<div class="box-flex-container">';
638  }
639  // Output Kanban
640  print $warehouse->getKanbanView('');
641 
642  if ($i == ($imaxinloop - 1)) {
643  print '</div>';
644  print '</td></tr>';
645  }
646  } else {
647  // Show here line of result
648  print '<tr class="oddeven">';
649 
650  // Action column
651  if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
652  print '<td class="nowrap center">';
653  if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
654  $selected = 0;
655  if (in_array($obj->rowid, $arrayofselected)) {
656  $selected = 1;
657  }
658  print '<input id="cb'.$obj->rowid.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected ? ' checked="checked"' : '').'>';
659  }
660  print '</td>';
661  }
662  foreach ($warehouse->fields as $key => $val) {
663  if ($key == 'statut') {
664  continue;
665  }
666  $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
667  if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
668  $cssforfield .= ($cssforfield ? ' ' : '').'center';
669  } elseif ($key == 'status') {
670  $cssforfield .= ($cssforfield ? ' ' : '').'center';
671  }
672 
673  if (in_array($val['type'], array('timestamp'))) {
674  $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
675  } elseif ($key == 'ref') {
676  $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
677  }
678 
679  if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $key != 'status' && empty($val['arrayofkeyval'])) {
680  $cssforfield .= ($cssforfield ? ' ' : '').'right';
681  }
682  if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) {
683  $cssforfield = 'tdoverflowmax100';
684  }
685 
686  if (!empty($arrayfields['t.'.$key]['checked'])) {
687  print '<td'.($cssforfield ? ' class="'.$cssforfield.'"' : '').'>';
688  if ($key == 'statut') {
689  print $warehouse->getLibStatut(5);
690  }
691  if ($key == 'phone') {
692  print dol_print_phone($obj->phone, '', 0, $obj->rowid, 'AC_TEL');
693  } elseif ($key == 'fax') {
694  print dol_print_phone($obj->fax, '', 0, $obj->rowid, 'AC_FAX');
695  } else {
696  print $warehouse->showOutputField($val, $key, $warehouse->$key, '');
697  }
698  print '</td>';
699  if (!$i) {
700  $totalarray['nbfield']++;
701  }
702  if (!empty($val['isameasure']) && $val['isameasure'] == 1) {
703  if (!$i) {
704  $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key;
705  }
706  if (!isset($totalarray['val'])) {
707  $totalarray['val'] = array();
708  }
709  if (!isset($totalarray['val']['t.'.$key])) {
710  $totalarray['val']['t.'.$key] = 0;
711  }
712  $totalarray['val']['t.'.$key] += $warehouse->$key;
713  }
714  }
715  }
716 
717  // Stock qty
718  if (!empty($arrayfields["stockqty"]['checked'])) {
719  print '<td class="right">'.price2num($obj->stockqty, 5).'</td>';
720  if (!$i) {
721  $totalarray['nbfield']++;
722  }
723  if (!$i) {
724  $totalarray['pos'][$totalarray['nbfield']] = 'stockqty';
725  }
726  }
727 
728  // PMP value
729  if (!empty($arrayfields["estimatedvalue"]['checked'])) {
730  print '<td class="right">';
731  if (price2num($obj->estimatedvalue, 'MT')) {
732  print '<span class="amount">'.price(price2num($obj->estimatedvalue, 'MT'), 1).'</span>';
733  } else {
734  print '';
735  }
736  print '</td>';
737  if (!$i) {
738  $totalarray['nbfield']++;
739  }
740  if (!$i) {
741  $totalarray['pos'][$totalarray['nbfield']] = 'estimatedvalue';
742  }
743  }
744 
745  // Selling value
746  if (!empty($arrayfields["estimatedstockvaluesell"]['checked'])) {
747  print '<td class="right">';
748  if (empty($conf->global->PRODUIT_MULTIPRICES)) {
749  if ($obj->sellvalue) {
750  print '<span class="amount">'.price(price2num($obj->sellvalue, 'MT'), 1).'</span>';
751  }
752  } else {
753  $htmltext = $langs->trans("OptionMULTIPRICESIsOn");
754  print $form->textwithtooltip('<span class="opacitymedium">'.$langs->trans("Variable").'</span>', $htmltext);
755  }
756  print '</td>';
757  if (!$i) {
758  $totalarray['nbfield']++;
759  }
760  if (!$i) {
761  $totalarray['pos'][$totalarray['nbfield']] = 'estimatedstockvaluesell';
762  }
763  }
764 
765  // Extra fields
766  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
767  // Fields from hook
768  $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray);
769  $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook
770  print $hookmanager->resPrint;
771 
772  // Status
773  if (!empty($arrayfields['t.statut']['checked'])) {
774  print '<td class="center">'.$warehouse->LibStatut($obj->statut, 5).'</td>';
775  if (!$i) {
776  $totalarray['nbfield']++;
777  }
778  }
779 
780  // Action column
781  if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
782  print '<td class="nowrap center">';
783  if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
784  $selected = 0;
785  if (in_array($obj->rowid, $arrayofselected)) {
786  $selected = 1;
787  }
788  print '<input id="cb'.$obj->rowid.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected ? ' checked="checked"' : '').'>';
789  }
790  print '</td>';
791  }
792  if (!$i) {
793  $totalarray['nbfield']++;
794  }
795 
796  print '</tr>'."\n";
797  }
798 
799  $i++;
800 }
801 
802 if ($totalnboflines - $offset <= $limit) {
803  // Show total line
804  include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
805 }
806 
807 // If no record found
808 if ($num == 0) {
809  $colspan = 1;
810  foreach ($arrayfields as $key => $val) {
811  if (!empty($val['checked'])) {
812  $colspan++;
813  }
814  }
815  print '<tr><td colspan="'.$colspan.'" class="opacitymedium">'.$langs->trans("NoRecordFound").'</td></tr>';
816 }
817 
818 $db->free($resql);
819 
820 $parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql);
821 $reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object); // Note that $action and $object may have been modified by hook
822 print $hookmanager->resPrint;
823 
824 print '</table>'."\n";
825 print '</div>'."\n";
826 
827 print '</form>'."\n";
828 
829 if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
830  $hidegeneratedfilelistifempty = 1;
831  if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
832  $hidegeneratedfilelistifempty = 0;
833  }
834 
835  require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
836  $formfile = new FormFile($db);
837 
838  // Show list of available documents
839  $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
840  $urlsource .= str_replace('&amp;', '&', $param);
841 
842  $filedir = $diroutputmassaction;
843  $genallowed = $user->rights->stock->lire;
844  $delallowed = $user->rights->stock->creer;
845 
846  print $formfile->showdocuments('massfilesarea_stock', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
847 }
848 
849 // End of page
850 llxFooter();
851 $db->close();
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:118
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 warehouses.
Class to manage standard extra fields.
Class to manage forms for categories.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:745
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
dol_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...
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.
natural_search($fields, $value, $mode=0, $nofirstand=0)
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
dol_print_phone($phone, $countrycode='', $cid=0, $socid=0, $addlink='', $separ="&nbsp;", $withpicto='', $titlealt='', $adddivfloat=0)
Format phone numbers according to country.
dol_now($mode='auto')
Return date for now.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
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...
dol_eval($s, $returnvalue=0, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $disablesortlink=0, $tooltip='', $forcenowrapcolumntitle=0)
Get 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.
if(!function_exists('utf8_encode')) if(!function_exists('utf8_decode')) getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
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.
$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.