dolibarr 21.0.0-alpha
list.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2007-2017 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18
25// Load Dolibarr environment
26require '../../main.inc.php';
27require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcategory.class.php';
28require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
29require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
30require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
31require_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php';
32
33// Load translation files required by the page
34$langs->loadLangs(array("stocks", "other"));
35
36$action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ...
37$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
38$show_files = GETPOSTINT('show_files'); // Show files area generated by bulk actions ?
39$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation
40$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button
41$toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list
42$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
43$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
44$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
45$mode = GETPOST('mode', 'aZ'); // The output mode ('list', 'kanban', 'hierarchy', 'calendar', ...)
46
47$id = GETPOSTINT('id');
48
49// Load variable for pagination
50$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
51$sortfield = GETPOST('sortfield', 'aZ09comma');
52$sortorder = GETPOST('sortorder', 'aZ09comma');
53$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
54if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
55 // If $page is not defined, or '' or -1 or if we click on clear filters
56 $page = 0;
57}
58$offset = $limit * $page;
59$pageprev = $page - 1;
60$pagenext = $page + 1;
61
62// Initialize a technical objects
63$object = new Inventory($db);
64$extrafields = new ExtraFields($db);
65// no inventory docs yet
66// $diroutputmassaction = $conf->inventory->dir_output.'/temp/massgeneration/'.$user->id;
67$diroutputmassaction = null;
68$hookmanager->initHooks(array('inventorylist')); // Note that conf->hooks_modules contains array
69// Fetch optionals attributes and labels
70$extrafields->fetch_name_optionals_label($object->table_element);
71$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
72
73// Default sort order (if not yet defined by previous GETPOST)
74if (!$sortfield) {
75 reset($object->fields); // Reset is required to avoid key() to return null.
76 $sortfield = "t.".key($object->fields); // Set here default search field. By default 1st field in definition.
77}
78if (!$sortorder) {
79 $sortorder = "ASC";
80}
81
82// Initialize array of search criteria
83$search_all = GETPOST('search_all', 'alphanohtml');
84$search = array();
85foreach ($object->fields as $key => $val) {
86 if (GETPOST('search_'.$key, 'alpha') !== '') {
87 $search[$key] = GETPOST('search_'.$key, 'alpha');
88 }
89 if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
90 $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOSTINT('search_'.$key.'_dtstartmonth'), GETPOSTINT('search_'.$key.'_dtstartday'), GETPOSTINT('search_'.$key.'_dtstartyear'));
91 $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOSTINT('search_'.$key.'_dtendmonth'), GETPOSTINT('search_'.$key.'_dtendday'), GETPOSTINT('search_'.$key.'_dtendyear'));
92 }
93}
94$searchCategoryProductOperator = 0;
95if (GETPOSTISSET('formfilteraction')) {
96 $searchCategoryProductOperator = GETPOSTINT('search_category_product_operator');
97} elseif (getDolGlobalString('MAIN_SEARCH_CAT_OR_BY_DEFAULT')) {
98 $searchCategoryProductOperator = getDolGlobalString('MAIN_SEARCH_CAT_OR_BY_DEFAULT');
99}
100$searchCategoryProductList = GETPOST('search_category_product_list', 'array');
101
102// List of fields to search into when doing a "search in all"
103$fieldstosearchall = array();
104foreach ($object->fields as $key => $val) {
105 if (!empty($val['searchall'])) {
106 $fieldstosearchall['t.'.$key] = $val['label'];
107 }
108}
109
110// Definition of array of fields for columns
111$arrayfields = array();
112foreach ($object->fields as $key => $val) {
113 // If $val['visible']==0, then we never show the field
114 if (!empty($val['visible'])) {
115 $visible = (int) dol_eval((string) $val['visible'], 1);
116 $arrayfields['t.'.$key] = array(
117 'label'=>$val['label'],
118 'checked'=>(($visible < 0) ? 0 : 1),
119 'enabled'=>(abs($visible) != 3 && (bool) dol_eval($val['enabled'], 1)),
120 'position'=>$val['position'],
121 'help'=> isset($val['help']) ? $val['help'] : ''
122 );
123 }
124}
125// Extra fields
126include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
127
128$object->fields = dol_sort_array($object->fields, 'position');
129$arrayfields = dol_sort_array($arrayfields, 'position');
130
131$permissiontoread = $user->hasRight('stock', 'lire');
132$permissiontoadd = $user->hasRight('stock', 'creer');
133$permissiontodelete = $user->hasRight('stock', 'supprimer');
134
135// Security check
136$socid = 0;
137if ($user->socid > 0) { // Protection if external user
138 //$socid = $user->socid;
140}
141if (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS')) {
142 $result = restrictedArea($user, 'stock');
143} else {
144 $result = restrictedArea($user, 'stock', 0, '', 'inventory_advance');
145}
146
147
148/*
149 * Actions
150 */
151
152if (GETPOST('cancel', 'alpha')) {
153 $action = 'list';
154 $massaction = '';
155}
156if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
157 $massaction = '';
158}
159
160$parameters = array();
161$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
162if ($reshook < 0) {
163 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
164}
165
166if (empty($reshook)) {
167 // Selection of new fields
168 include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
169
170 // Purge search criteria
171 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
172 foreach ($object->fields as $key => $val) {
173 $search[$key] = '';
174 if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
175 $search[$key.'_dtstart'] = '';
176 $search[$key.'_dtend'] = '';
177 }
178 }
179 $searchCategoryProductList = array();
180 $toselect = array();
181 $search_array_options = array();
182 }
183 if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
184 || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
185 $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
186 }
187
188 // Mass actions
189 $objectclass = 'Inventory';
190 $objectlabel = 'Inventory';
191 $uploaddir = $conf->stock->dir_output;
192 include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
193}
194
195
196
197/*
198 * View
199 */
200
201$form = new Form($db);
202
203$now = dol_now();
204
205$title = $langs->trans('Inventories');
206//$help_url="EN:Module_Inventory|FR:Module_Inventory_FR|ES:Módulo_Inventory";
207$help_url = '';
208$morejs = array();
209$morecss = array();
210
211
212// Build and execute select
213// --------------------------------------------------------------------
214$sql = 'SELECT ';
215$sql .= $object->getFieldList('t');
216// Add fields from extrafields
217if (!empty($extrafields->attributes[$object->table_element]['label'])) {
218 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
219 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
220 }
221}
222// Add fields from hooks
223$parameters = array();
224$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
225$sql .= $hookmanager->resPrint;
226$sql = preg_replace('/,\s*$/', '', $sql);
227
228$sqlfields = $sql; // $sql fields to remove for count total
229
230$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
231if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
232 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)";
233}
234// Add table from hooks
235$parameters = array();
236$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
237$sql .= $hookmanager->resPrint;
238if ($object->ismultientitymanaged == 1) {
239 $sql .= " WHERE t.entity IN (".getEntity($object->element).")";
240} else {
241 $sql .= " WHERE 1 = 1";
242}
243foreach ($search as $key => $val) {
244 if (array_key_exists($key, $object->fields)) {
245 if ($key == 'status' && $search[$key] == -1) {
246 continue;
247 }
248 $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0);
249 if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) {
250 if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) {
251 $search[$key] = '';
252 }
253 $mode_search = 2;
254 }
255 if ($search[$key] != '') {
256 $sql .= natural_search("t.".$db->escape($key), $search[$key], (($key == 'status') ? 2 : $mode_search));
257 }
258 } else {
259 if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') {
260 $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key);
261 if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) {
262 if (preg_match('/_dtstart$/', $key)) {
263 $sql .= " AND t.".$db->escape($columnName)." >= '".$db->idate($search[$key])."'";
264 }
265 if (preg_match('/_dtend$/', $key)) {
266 $sql .= " AND t.".$db->escape($columnName)." <= '".$db->idate($search[$key])."'";
267 }
268 }
269 }
270 }
271}
272
273if ($search_all) {
274 $sql .= natural_search(array_keys($fieldstosearchall), $search_all);
275}
276// Search for tag/category ($searchCategoryProductList is an array of ID)
277if (!empty($searchCategoryProductList)) {
278 $searchCategoryProductSqlList = array();
279 $listofcategoryid = '';
280 foreach ($searchCategoryProductList as $searchCategoryProduct) {
281 if (intval($searchCategoryProduct) == -2) {
282 $searchCategoryProductSqlList[] = "NOT EXISTS (SELECT ck.fk_product FROM ".MAIN_DB_PREFIX."categorie_product as ck WHERE p.rowid = ck.fk_product)";
283 } elseif (intval($searchCategoryProduct) > 0) {
284 if ($searchCategoryProductOperator == 0) {
285 $searchCategoryProductSqlList[] = " EXISTS (SELECT ck.fk_product FROM ".MAIN_DB_PREFIX."categorie_product as ck WHERE p.rowid = ck.fk_product AND ck.fk_categorie = ".((int) $searchCategoryProduct).")";
286 } else {
287 $listofcategoryid .= ($listofcategoryid ? ', ' : '') .((int) $searchCategoryProduct);
288 }
289 }
290 }
291 if ($listofcategoryid) {
292 $searchCategoryProductSqlList[] = " EXISTS (SELECT ck.fk_product FROM ".MAIN_DB_PREFIX."categorie_product as ck WHERE p.rowid = ck.fk_product AND ck.fk_categorie IN (".$db->sanitize($listofcategoryid)."))";
293 }
294 if ($searchCategoryProductOperator == 1) {
295 if (!empty($searchCategoryProductSqlList)) {
296 $sql .= " AND (".implode(' OR ', $searchCategoryProductSqlList).")";
297 }
298 } else {
299 if (!empty($searchCategoryProductSqlList)) {
300 $sql .= " AND (".implode(' AND ', $searchCategoryProductSqlList).")";
301 }
302 }
303}
304// Add where from extra fields
305include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
306// Add where from hooks
307$parameters = array();
308$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
309$sql .= $hookmanager->resPrint;
310
311/* If a group by is required
312$sql.= " GROUP BY ";
313foreach($object->fields as $key => $val) {
314 $sql .= "t.".$db->escape($key).", ";
315}
316// Add fields from extrafields
317if (!empty($extrafields->attributes[$object->table_element]['label'])) {
318 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
319 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : '');
320 }
321}
322// Add where from hooks
323$parameters=array();
324$reshook=$hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook
325$sql.=$hookmanager->resPrint;
326$sql=preg_replace('/,\s*$/','', $sql);
327*/
328
329// Count total nb of records
330$nbtotalofrecords = '';
331if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
332 /* The fast and low memory method to get and count full list converts the sql into a sql count */
333 $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
334 $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
335 $resql = $db->query($sqlforcount);
336 if ($resql) {
337 $objforcount = $db->fetch_object($resql);
338 $nbtotalofrecords = $objforcount->nbtotalofrecords;
339 } else {
340 dol_print_error($db);
341 }
342
343 if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
344 $page = 0;
345 $offset = 0;
346 }
347 $db->free($resql);
348}
349
350// Complete request and execute it with limit
351$sql .= $db->order($sortfield, $sortorder);
352if ($limit) {
353 $sql .= $db->plimit($limit + 1, $offset);
354}
355
356$resql = $db->query($sql);
357if (!$resql) {
358 dol_print_error($db);
359 exit;
360}
361
362$num = $db->num_rows($resql);
363
364// Direct jump if only one record found
365if ($num == 1 && getDolGlobalString('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.'/inventory/card.php?id='.$id);
369 exit;
370}
371
372
373// Output page
374// --------------------------------------------------------------------
375
376llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'bodyforlist'); // Can use also classforhorizontalscrolloftabs instead of bodyforlist for no horizontal scroll
377
378$arrayofselected = is_array($toselect) ? $toselect : array();
379
380$param = '';
381if (!empty($mode)) {
382 $param .= '&mode='.urlencode($mode);
383}
384if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
385 $param .= '&contextpage='.urlencode($contextpage);
386}
387if ($limit > 0 && $limit != $conf->liste_limit) {
388 $param .= '&limit='.((int) $limit);
389}
390foreach ($search as $key => $val) {
391 if (is_array($search[$key])) {
392 foreach ($search[$key] as $skey) {
393 if ($skey != '') {
394 $param .= '&search_'.$key.'[]='.urlencode($skey);
395 }
396 }
397 } elseif (preg_match('/(_dtstart|_dtend)$/', $key) && !empty($val)) {
398 $param .= '&search_'.$key.'month='.(GETPOSTINT('search_'.$key.'month'));
399 $param .= '&search_'.$key.'day='.(GETPOSTINT('search_'.$key.'day'));
400 $param .= '&search_'.$key.'year='.(GETPOSTINT('search_'.$key.'year'));
401 } elseif ($search[$key] != '') {
402 $param .= '&search_'.$key.'='.urlencode($search[$key]);
403 }
404}
405if ($optioncss != '') {
406 $param .= '&optioncss='.urlencode($optioncss);
407}
408foreach ($searchCategoryProductList as $searchCategoryProduct) {
409 $param .= "&search_category_product_list[]=".urlencode($searchCategoryProduct);
410}
411// Add $param from extra fields
412include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
413// Add $param from hooks
414$parameters = array('param' => &$param);
415$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
416$param .= $hookmanager->resPrint;
417
418// List of mass actions available
419$arrayofmassactions = array(
420 //'validate'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"),
421 //'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"),
422 //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
423 //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
424);
425if (!empty($permissiontodelete)) {
426 $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
427}
428if (GETPOSTINT('nomassaction') || in_array($massaction, array('presend', 'predelete'))) {
429 $arrayofmassactions = array();
430}
431$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
432
433print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
434if ($optioncss != '') {
435 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
436}
437print '<input type="hidden" name="token" value="'.newToken().'">';
438print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
439print '<input type="hidden" name="action" value="list">';
440print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
441print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
442print '<input type="hidden" name="page" value="'.$page.'">';
443print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
444print '<input type="hidden" name="page_y" value="">';
445print '<input type="hidden" name="mode" value="'.$mode.'">';
446
447$newcardbutton = '';
448$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'));
449$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'));
450$newcardbutton .= dolGetButtonTitleSeparator();
451$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/product/inventory/card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd);
452
453print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, $object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1);
454
455// Add code for pre mass action (confirmation or email presend form)
456$topicmail = "Information";
457$modelmail = "inventory";
458$objecttmp = new Inventory($db);
459$trackid = 'stockinv'.$object->id;
460include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
461
462if ($search_all) {
463 $setupstring = '';
464 foreach ($fieldstosearchall as $key => $val) {
465 $fieldstosearchall[$key] = $langs->trans($val);
466 $setupstring .= $key."=".$val.";";
467 }
468 print '<!-- Search done like if MYOBJECT_QUICKSEARCH_ON_FIELDS = '.$setupstring.' -->'."\n";
469 print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).implode(', ', $fieldstosearchall).'</div>'."\n";
470}
471
472$moreforfilter = '';
473/*$moreforfilter.='<div class="divsearchfield">';
474$moreforfilter.= $langs->trans('MyFilter') . ': <input type="text" name="search_myfield" value="'.dol_escape_htmltag($search_myfield).'">';
475$moreforfilter.= '</div>';*/
476
477// Filter on categories
478if (getDolGlobalString('MAIN_SEARCH_CATEGORY_PRODUCT_ON_LISTS') && isModEnabled('category') && $user->hasRight('categorie', 'lire')) {
479 $formcategory = new FormCategory($db);
480 $moreforfilter .= $formcategory->getFilterBox(Categorie::TYPE_PRODUCT, $searchCategoryProductList, 'minwidth300', $searchCategoryProductList ? $searchCategoryProductList : 0);
481 /*
482 $moreforfilter .= '<div class="divsearchfield">';
483 $tmptitle = $langs->transnoentities('ProductsCategoriesShort');
484 $moreforfilter .= img_picto($tmptitle, 'category', 'class="pictofixedwidth"');
485 $categoriesProductArr = $form->select_all_categories(Categorie::TYPE_PRODUCT, '', '', 64, 0, 3);
486 $categoriesProductArr[-2] = '- '.$langs->trans('NotCategorized').' -';
487 $moreforfilter .= Form::multiselectarray('search_category_product_list', $categoriesProductArr, $searchCategoryProductList, 0, 0, 'minwidth300', 0, 0, '', 'category', $tmptitle);
488 $moreforfilter .= ' <input type="checkbox" class="valignmiddle" id="search_category_product_operator" name="search_category_product_operator" value="1"'.($searchCategoryProductOperator == 1 ? ' checked="checked"' : '').'/>';
489 $moreforfilter .= $form->textwithpicto('', $langs->trans('UseOrOperatorForCategories') . ' : ' . $tmptitle, 1, 'help', '', 0, 2, 'tooltip_cat_pro'); // Tooltip on click
490 $moreforfilter .= '</div>';
491 */
492}
493
494$parameters = array();
495$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
496if (empty($reshook)) {
497 $moreforfilter .= $hookmanager->resPrint;
498} else {
499 $moreforfilter = $hookmanager->resPrint;
500}
501
502if (!empty($moreforfilter)) {
503 print '<div class="liste_titre liste_titre_bydiv centpercent">';
504 print $moreforfilter;
505 $parameters = array();
506 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
507 print $hookmanager->resPrint;
508 print '</div>';
509}
510
511$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
512$htmlofselectarray = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')); // This also change content of $arrayfields with user setup
513$selectedfields = ($mode != 'kanban' ? $htmlofselectarray : '');
514$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
515
516print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
517print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
518
519
520// Fields title search
521// --------------------------------------------------------------------
522print '<tr class="liste_titre_filter">';
523// Action column
524if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
525 print '<td class="liste_titre center maxwidthsearch">';
526 $searchpicto = $form->showFilterButtons('left');
527 print $searchpicto;
528 print '</td>';
529}
530foreach ($object->fields as $key => $val) {
531 $searchkey = empty($search[$key]) ? '' : $search[$key];
532 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
533 if ($key == 'status') {
534 $cssforfield .= ($cssforfield ? ' ' : '').'center';
535 } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
536 $cssforfield .= ($cssforfield ? ' ' : '').'center';
537 } elseif (in_array($val['type'], array('timestamp'))) {
538 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
539 } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('id', 'rowid', 'ref', 'status')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) {
540 $cssforfield .= ($cssforfield ? ' ' : '').'right';
541 }
542 if (!empty($arrayfields['t.'.$key]['checked'])) {
543 print '<td class="liste_titre'.($cssforfield ? ' '.$cssforfield : '').($key == 'status' ? ' parentonrightofpage' : '').'">';
544 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
545 print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100'.($key == 'status' ? ' search_status width100 onrightofpage' : ''), 1);
546 } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) {
547 print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', $cssforfield.' maxwidth250', 1);
548 } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
549 print '<div class="nowrap">';
550 print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
551 print '</div>';
552 print '<div class="nowrap">';
553 print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
554 print '</div>';
555 } elseif ($key == 'lang') {
556 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
557 $formadmin = new FormAdmin($db);
558 print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth100imp maxwidth125', 2);
559 } else {
560 print '<input type="text" class="flat maxwidth75" name="search_'.$key.'" value="'.dol_escape_htmltag(isset($search[$key]) ? $search[$key] : '').'">';
561 }
562 print '</td>';
563 }
564}
565// Extra fields
566include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
567
568// Fields from hook
569$parameters = array('arrayfields'=>$arrayfields);
570$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
571print $hookmanager->resPrint;
572// Action column
573if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
574 print '<td class="liste_titre center maxwidthsearch">';
575 $searchpicto = $form->showFilterButtons();
576 print $searchpicto;
577 print '</td>';
578}
579print '</tr>'."\n";
580
581$totalarray = array();
582$totalarray['nbfield'] = 0;
583
584// Fields title label
585// --------------------------------------------------------------------
586print '<tr class="liste_titre">';
587// Action column
588if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
589 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
590 $totalarray['nbfield']++;
591}
592foreach ($object->fields as $key => $val) {
593 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
594 if ($key == 'status') {
595 $cssforfield .= ($cssforfield ? ' ' : '').'center';
596 } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
597 $cssforfield .= ($cssforfield ? ' ' : '').'center';
598 } elseif (in_array($val['type'], array('timestamp'))) {
599 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
600 } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('id', 'rowid', 'ref', 'status')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) {
601 $cssforfield .= ($cssforfield ? ' ' : '').'right';
602 }
603 $cssforfield = preg_replace('/small\s*/', '', $cssforfield); // the 'small' css must not be used for the title label
604 if (!empty($arrayfields['t.'.$key]['checked'])) {
605 print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''), 0, (empty($val['helplist']) ? '' : $val['helplist']))."\n";
606 $totalarray['nbfield']++;
607 }
608}
609// Extra fields
610include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
611// Hook fields
612$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder, 'totalarray'=>&$totalarray);
613$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
614print $hookmanager->resPrint;
615// Action column
616if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
617 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
618 $totalarray['nbfield']++;
619}
620print '</tr>'."\n";
621
622
623// Detect if we need a fetch on each output line
624$needToFetchEachLine = 0;
625if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) {
626 foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) {
627 if (!is_null($val) && preg_match('/\$object/', $val)) {
628 $needToFetchEachLine++; // There is at least one compute field that use $object
629 }
630 }
631}
632
633// Loop on record
634// --------------------------------------------------------------------
635$i = 0;
636$savnbfield = $totalarray['nbfield'];
637$totalarray = array();
638$totalarray['nbfield'] = 0;
639$imaxinloop = ($limit ? min($num, $limit) : $num);
640while ($i < $imaxinloop) {
641 $obj = $db->fetch_object($resql);
642 if (empty($obj)) {
643 break; // Should not happen
644 }
645
646 // Store properties in $object
647 $object->setVarsFromFetchObj($obj);
648
649 if ($mode == 'kanban') {
650 if ($i == 0) {
651 print '<tr class="trkanban"><td colspan="'.$savnbfield.'">';
652 print '<div class="box-flex-container kanban">';
653 }
654 // Output Kanban
655 $selected = -1;
656 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
657 $selected = 0;
658 if (in_array($object->id, $arrayofselected)) {
659 $selected = 1;
660 }
661 }
662 print $object->getKanbanView('', array('selected' => $selected));
663 if ($i == ($imaxinloop - 1)) {
664 print '</div>';
665 print '</td></tr>';
666 }
667 } else {
668 // Show here line of result
669 $j = 0;
670 print '<tr data-rowid="'.$object->id.'" class="oddeven">';
671 // Action column
672 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
673 print '<td class="nowrap center">';
674 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
675 $selected = 0;
676 if (in_array($object->id, $arrayofselected)) {
677 $selected = 1;
678 }
679 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
680 }
681 print '</td>';
682 if (!$i) {
683 $totalarray['nbfield']++;
684 }
685 }
686 foreach ($object->fields as $key => $val) {
687 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
688 if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
689 $cssforfield .= ($cssforfield ? ' ' : '').'center';
690 } elseif ($key == 'status') {
691 $cssforfield .= ($cssforfield ? ' ' : '').'center';
692 }
693
694 if (in_array($val['type'], array('timestamp'))) {
695 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
696 } elseif ($key == 'ref') {
697 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
698 }
699
700 if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status')) && empty($val['arrayofkeyval'])) {
701 $cssforfield .= ($cssforfield ? ' ' : '').'right';
702 }
703
704 if (!empty($arrayfields['t.'.$key]['checked'])) {
705 print '<td'.($cssforfield ? ' class="'.$cssforfield.(preg_match('/tdoverflow/', $cssforfield) ? ' classfortooltip' : '').'"' : '');
706 if (preg_match('/tdoverflow/', $cssforfield) && !is_numeric($object->$key)) {
707 print ' title="'.dol_escape_htmltag($object->$key).'"';
708 }
709 print '>';
710 if ($key == 'status') {
711 print $object->getLibStatut(5);
712 } elseif ($key == 'rowid') {
713 print $object->showOutputField($val, $key, $object->id, '');
714 } else {
715 print $object->showOutputField($val, $key, $object->$key, '');
716 }
717 print '</td>';
718 if (!$i) {
719 $totalarray['nbfield']++;
720 }
721 if (!empty($val['isameasure']) && $val['isameasure'] == 1) {
722 if (!$i) {
723 $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key;
724 }
725 if (!isset($totalarray['val'])) {
726 $totalarray['val'] = array();
727 }
728 if (!isset($totalarray['val']['t.'.$key])) {
729 $totalarray['val']['t.'.$key] = 0;
730 }
731 $totalarray['val']['t.'.$key] += $object->$key;
732 }
733 }
734 }
735 // Extra fields
736 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
737 // Fields from hook
738 $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray);
739 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
740 print $hookmanager->resPrint;
741 // Action column
742 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
743 print '<td class="nowrap center">';
744 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
745 $selected = 0;
746 if (in_array($object->id, $arrayofselected)) {
747 $selected = 1;
748 }
749 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
750 }
751 print '</td>';
752 if (!$i) {
753 $totalarray['nbfield']++;
754 }
755 }
756
757 print '</tr>'."\n";
758 }
759
760 $i++;
761}
762
763// Show total line
764include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
765
766
767// If no record found
768if ($num == 0) {
769 $colspan = 1;
770 foreach ($arrayfields as $key => $val) {
771 if (!empty($val['checked'])) {
772 $colspan++;
773 }
774 }
775 print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
776}
777
778
779$db->free($resql);
780
781$parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql);
782$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
783print $hookmanager->resPrint;
784
785print '</table>'."\n";
786print '</div>'."\n";
787
788print '</form>'."\n";
789// no inventory docs yet
790/*
791if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
792 $hidegeneratedfilelistifempty = 1;
793 if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
794 $hidegeneratedfilelistifempty = 0;
795 }
796
797 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
798 $formfile = new FormFile($db);
799
800 // Show list of available documents
801 $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
802 $urlsource .= str_replace('&amp;', '&', $param);
803
804 $filedir = $diroutputmassaction;
805 $genallowed = $permissiontoread;
806 $delallowed = $permissiontoadd;
807
808 print $formfile->showdocuments('massfilesarea_mymodule', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
809}
810*/
811// End of page
812llxFooter();
813$db->close();
$id
Definition account.php:39
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:70
Class to manage standard extra fields.
Class to generate html code for admin pages.
Class to manage forms for categories.
Class to manage generation of HTML components Only common components must be here.
Class for Inventory.
llxFooter()
Footer empty.
Definition document.php:107
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
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.
dol_eval($s, $returnvalue=1, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
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_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by the value of a given key, which produces ascending (default) or descending out...
getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $disablesortlink=0, $tooltip='', $forcenowrapcolumntitle=0)
Get title line of an array.
dolGetButtonTitleSeparator($moreClass="")
Add space between dolGetButtonTitle.
print_barre_liste($title, $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.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
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.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.