dolibarr  17.0.4
productlot_list.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2007-2016 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2018-2021 Ferran Marcet <fmarcet@2byte.es>
4  * Copyright (C) 2019 Frédéric France <frederic.france@netlogic.fr>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
27 // Load Dolibarr environment
28 require '../../main.inc.php';
29 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
30 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
31 require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
32 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php';
34 
35 // Load translation files required by the page
36 $langs->loadLangs(array('stocks', 'productbatch', 'other', 'users'));
37 
38 // Get parameters
39 $id = GETPOST('id', 'int');
40 $action = GETPOST('action', 'aZ09');
41 $massaction = GETPOST('massaction', 'alpha');
42 $backtopage = GETPOST('backtopage', 'alpha');
43 $toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list
44 $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'productlotlist'; // To manage different context of search
45 $optioncss = GETPOST('optioncss', 'alpha');
46 $mode = GETPOST('mode', 'alpha');
47 
48 $search_entity = GETPOST('search_entity', 'int');
49 $search_product = GETPOST('search_product', 'alpha');
50 $search_batch = GETPOST('search_batch', 'alpha');
51 $search_fk_user_creat = GETPOST('search_fk_user_creat', 'int');
52 $search_fk_user_modif = GETPOST('search_fk_user_modif', 'int');
53 $search_import_key = GETPOST('search_import_key', 'int');
54 
55 // Load variable for pagination
56 $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
57 $sortfield = GETPOST('sortfield', 'aZ09comma');
58 $sortorder = GETPOST('sortorder', 'aZ09comma');
59 $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
60 if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
61  // If $page is not defined, or '' or -1 or if we click on clear filters
62  $page = 0;
63 }
64 $offset = $limit * $page;
65 $pageprev = $page - 1;
66 $pagenext = $page + 1;
67 
68 // Initialize technical object to manage hooks. Note that conf->hooks_modules contains array
69 $object = new Productlot($db);
70 $extrafields = new ExtraFields($db);
71 $diroutputmassaction = $conf->productbatch->dir_output.'/temp/massgeneration/'.$user->id;
72 $hookmanager->initHooks(array('product_lotlist'));
73 
74 // Fetch optionals attributes and labels
75 $extrafields->fetch_name_optionals_label($object->table_element);
76 //$extrafields->fetch_name_optionals_label($object->table_element_line);
77 
78 $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
79 
80 // Default sort order (if not yet defined by previous GETPOST)
81 if (!$sortfield) {
82  $sortfield = "t.fk_product,t.batch"; // Set here default search field. By default 1st field in definition.
83 }
84 if (!$sortorder) {
85  $sortorder = "ASC";
86 }
87 
88 // Initialize array of search criterias
89 $search_all = GETPOST('search_all', 'alphanohtml') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml');
90 $search = array();
91 foreach ($object->fields as $key => $val) {
92  if (GETPOST('search_'.$key, 'alpha') !== '') {
93  $search[$key] = GETPOST('search_'.$key, 'alpha');
94  }
95  if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
96  $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_'.$key.'_dtstartmonth', 'int'), GETPOST('search_'.$key.'_dtstartday', 'int'), GETPOST('search_'.$key.'_dtstartyear', 'int'));
97  $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int'));
98  }
99 }
100 
101 // List of fields to search into when doing a "search in all"
102 $fieldstosearchall = array();
103 foreach ($object->fields as $key => $val) {
104  if (!empty($val['searchall'])) {
105  $fieldstosearchall['t.'.$key] = $val['label'];
106  }
107 }
108 
109 // Definition of array of fields for columns
110 $arrayfields = array();
111 foreach ($object->fields as $key => $val) {
112  // If $val['visible']==0, then we never show the field
113  if (!empty($val['visible'])) {
114  $visible = (int) dol_eval($val['visible'], 1);
115  $arrayfields['t.'.$key] = array(
116  'label'=>$val['label'],
117  'checked'=>(($visible < 0) ? 0 : 1),
118  'enabled'=>(abs($visible) != 3 && dol_eval($val['enabled'], 1)),
119  'position'=>$val['position'],
120  'help'=> isset($val['help']) ? $val['help'] : ''
121  );
122  }
123 }
124 // Extra fields
125 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
126 
127 $object->fields = dol_sort_array($object->fields, 'position');
128 $arrayfields = dol_sort_array($arrayfields, 'position');
129 
130 $usercanread = $user->rights->produit->lire;
131 $usercancreate = $user->rights->produit->creer;
132 $usercandelete = $user->rights->produit->supprimer;
133 
134 $upload_dir = $conf->productbatch->multidir_output[$conf->entity];
135 
136 $permissiontoread = $usercanread;
137 $permissiontoadd = $usercancreate;
138 //$permissiontodelete = $usercandelete;
139 
140 // Security check
141 if (empty($conf->productbatch->enabled)) {
142  accessforbidden('Module not enabled');
143 }
144 $socid = 0;
145 if ($user->socid > 0) { // Protection if external user
146  //$socid = $user->socid;
147  accessforbidden();
148 }
149 //$result = restrictedArea($user, 'productbatch');
150 if (!$permissiontoread) accessforbidden();
151 
152 
153 /*
154  * Actions
155  */
156 
157 if (GETPOST('cancel', 'alpha')) {
158  $action = 'list';
159  $massaction = '';
160 }
161 if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
162  $massaction = '';
163 }
164 
165 $parameters = array();
166 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
167 if ($reshook < 0) {
168  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
169 }
170 
171 if (empty($reshook)) {
172  // Selection of new fields
173  include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
174 
175  // Purge search criteria
176  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
177  foreach ($object->fields as $key => $val) {
178  $search[$key] = '';
179  if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
180  $search[$key.'_dtstart'] = '';
181  $search[$key.'_dtend'] = '';
182  }
183  }
184  $toselect = array();
185  $search_array_options = array();
186  }
187  if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
188  || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
189  $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
190  }
191 
192  // Mass actions
193  $objectclass = 'ProductLot';
194  $objectlabel = 'LotSerial';
195  $uploaddir = $conf->productbatch->dir_output;
196  include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
197 }
198 
199 
200 /*
201  * View
202  */
203 
204 
205 $form = new Form($db);
206 
207 $now = dol_now();
208 
209 $help_url = 'EN:Module_Lot_/_Serial|FR:Module_Lot_/_Série';
210 $title = $langs->trans('LotSerialList');
211 $morejs = array();
212 $morecss = array();
213 
214 
215 // Build and execute select
216 // --------------------------------------------------------------------
217 $sql = 'SELECT ';
218 $sql .= $object->getFieldList('t');
219 // Add fields from extrafields
220 if (!empty($extrafields->attributes[$object->table_element]['label'])) {
221  foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
222  $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
223  }
224 }
225 // Add fields from hooks
226 $parameters = array();
227 $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
228 $sql .= preg_replace('/^,/', '', $hookmanager->resPrint);
229 $sql = preg_replace('/,\s*$/', '', $sql);
230 
231 $sqlfields = $sql;
232 
233 $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
234 if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
235  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)";
236 }
237 // Add table from hooks
238 $parameters = array();
239 $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook
240 $sql .= $hookmanager->resPrint;
241 if ($object->ismultientitymanaged == 1) {
242  $sql .= " WHERE t.entity IN (".getEntity($object->element).")";
243 } else {
244  $sql .= " WHERE 1 = 1";
245 }
246 foreach ($search as $key => $val) {
247  if (array_key_exists($key, $object->fields)) {
248  if ($key == 'status' && $search[$key] == -1) {
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) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) {
253  if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) {
254  $search[$key] = '';
255  }
256  $mode_search = 2;
257  }
258  if ($search[$key] != '') {
259  $sql .= natural_search("t.".$db->escape($key), $search[$key], (($key == 'status') ? 2 : $mode_search));
260  }
261  } else {
262  if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') {
263  $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key);
264  if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) {
265  if (preg_match('/_dtstart$/', $key)) {
266  $sql .= " AND t.".$db->escape($columnName)." >= '".$db->idate($search[$key])."'";
267  }
268  if (preg_match('/_dtend$/', $key)) {
269  $sql .= " AND t.".$db->escape($columnName)." <= '".$db->idate($search[$key])."'";
270  }
271  }
272  }
273  }
274 }
275 if ($search_all) {
276  $sql .= natural_search(array_keys($fieldstosearchall), $search_all);
277 }
278 //$sql.= dolSqlDateFilter("t.field", $search_xxxday, $search_xxxmonth, $search_xxxyear);
279 // Add where from extra fields
280 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
281 // Add where from hooks
282 $parameters = array();
283 $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook
284 $sql .= $hookmanager->resPrint;
285 
286 /* If a group by is required
287 $sql.= " GROUP BY ";
288 foreach($object->fields as $key => $val) {
289  $sql .= "t.".$db->escape($key).", ";
290 }
291 // Add fields from extrafields
292 if (!empty($extrafields->attributes[$object->table_element]['label'])) {
293  foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
294  $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : '');
295  }
296 }
297 // Add where from hooks
298 $parameters=array();
299 $reshook=$hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook
300 $sql.=$hookmanager->resPrint;
301 $sql=preg_replace('/,\s*$/','', $sql);
302 */
303 
304 // Count total nb of records
305 $nbtotalofrecords = '';
306 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
307  /* This old and fast method to get and count full list returns all record so use a high amount of memory.
308  $resql = $db->query($sql);
309  $nbtotalofrecords = $db->num_rows($resql);
310  */
311  /* The slow method does not consume memory on mysql (not tested on pgsql) */
312  /*$resql = $db->query($sql, 0, 'auto', 1);
313  while ($db->fetch_object($resql)) {
314  if (empty($nbtotalofrecords)) {
315  $nbtotalofrecords = 1; // We can't make +1 because init value is ''
316  } else {
317  $nbtotalofrecords++;
318  }
319  }*/
320  /* The fast and low memory method to get and count full list converts the sql into a sql count */
321  $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
322  $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
323 
324  $resql = $db->query($sqlforcount);
325  if ($resql) {
326  $objforcount = $db->fetch_object($resql);
327  $nbtotalofrecords = $objforcount->nbtotalofrecords;
328  } else {
329  dol_print_error($db);
330  }
331 
332  if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0
333  $page = 0;
334  $offset = 0;
335  }
336  $db->free($resql);
337 }
338 
339 // Complete request and execute it with limit
340 $sql .= $db->order($sortfield, $sortorder);
341 if ($limit) {
342  $sql .= $db->plimit($limit + 1, $offset);
343 }
344 
345 $resql = $db->query($sql);
346 if (!$resql) {
347  dol_print_error($db);
348  exit;
349 }
350 
351 $num = $db->num_rows($resql);
352 
353 $i = 0;
354 
355 // Direct jump if only one record found
356 if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) {
357  $obj = $db->fetch_object($resql);
358  $id = $obj->rowid;
359  header("Location: ".DOL_URL_ROOT.'/product/stock/productlot_card.php?id='.$id);
360  exit;
361 }
362 
363 
364 // Output page
365 // --------------------------------------------------------------------
366 
367 llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'bodyforlist');
368 
369 $arrayofselected = is_array($toselect) ? $toselect : array();
370 
371 $param = '';
372 if (!empty($mode)) {
373  $param .= '&mode='.urlencode($mode);
374 }
375 if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
376  $param .= '&contextpage='.urlencode($contextpage);
377 }
378 if ($limit > 0 && $limit != $conf->liste_limit) {
379  $param .= '&limit='.urlencode($limit);
380 }
381 foreach ($search as $key => $val) {
382  if (is_array($search[$key]) && count($search[$key])) {
383  foreach ($search[$key] as $skey) {
384  if ($skey != '') {
385  $param .= '&search_'.$key.'[]='.urlencode($skey);
386  }
387  }
388  } elseif ($search[$key] != '') {
389  $param .= '&search_'.$key.'='.urlencode($search[$key]);
390  }
391 }
392 if ($optioncss != '') {
393  $param .= '&optioncss='.urlencode($optioncss);
394 }
395 // Add $param from extra fields
396 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
397 // Add $param from hooks
398 $parameters = array();
399 $reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook
400 $param .= $hookmanager->resPrint;
401 
402 // List of mass actions available
403 $arrayofmassactions = array(
404  //'validate'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"),
405  //'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"),
406  //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
407  //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
408 );
409 if (!empty($permissiontodelete)) {
410  $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
411 }
412 if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) {
413  $arrayofmassactions = array();
414 }
415 $massactionbutton = $form->selectMassAction('', $arrayofmassactions);
416 
417 print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
418 if ($optioncss != '') {
419  print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
420 }
421 print '<input type="hidden" name="token" value="'.newToken().'">';
422 print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
423 print '<input type="hidden" name="action" value="list">';
424 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
425 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
426 print '<input type="hidden" name="page" value="'.$page.'">';
427 print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
428 print '<input type="hidden" name="mode" value="'.$mode.'">';
429 
430 $newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/product/stock/productlot_card.php', 1).'?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd);
431 
432 print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1);
433 
434 // Add code for pre mass action (confirmation or email presend form)
435 $topicmail = "Information";
436 $modelmail = "productlot";
437 $objecttmp = new Productlot($db);
438 $trackid = 'lot'.$object->id;
439 include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
440 
441 if ($search_all) {
442  $setupstring = '';
443  foreach ($fieldstosearchall as $key => $val) {
444  $fieldstosearchall[$key] = $langs->trans($val);
445  $setupstring .= $key."=".$val.";";
446  }
447  print '<!-- Search done like if PRODUCT_QUICKSEARCH_ON_FIELDS = '.$setupstring.' -->'."\n";
448  print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'</div>'."\n";
449 }
450 
451 // Filter on categories
452 $moreforfilter = '';
453 /*$moreforfilter.='<div class="divsearchfield">';
454  $moreforfilter.= $langs->trans('MyFilter') . ': <input type="text" name="search_myfield" value="'.dol_escape_htmltag($search_myfield).'">';
455  $moreforfilter.= '</div>';*/
456 
457 $parameters = array();
458 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
459 if (empty($reshook)) {
460  $moreforfilter .= $hookmanager->resPrint;
461 } else {
462  $moreforfilter = $hookmanager->resPrint;
463 }
464 
465 if (!empty($moreforfilter)) {
466  print '<div class="liste_titre liste_titre_bydiv centpercent">';
467  print $moreforfilter;
468  $parameters = array();
469  $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
470  print $hookmanager->resPrint;
471  print '</div>';
472 }
473 
474 $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
475 $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // This also change content of $arrayfields
476 $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
477 
478 print '<div class="div-table-responsive">';
479 print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
480 
481 
482 // Fields title search
483 // --------------------------------------------------------------------
484 print '<tr class="liste_titre_filter">';
485 // Action column
486 if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
487  print '<td class="liste_titre maxwidthsearch">';
488  $searchpicto = $form->showFilterButtons('left');
489  print $searchpicto;
490  print '</td>';
491 }
492 foreach ($object->fields as $key => $val) {
493  $searchkey = empty($search[$key]) ? '' : $search[$key];
494  $cssforfield = (empty($val['css']) ? '' : $val['css']);
495  if ($key == 'status') {
496  $cssforfield .= ($cssforfield ? ' ' : '').'center';
497  } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
498  $cssforfield .= ($cssforfield ? ' ' : '').'center';
499  } elseif (in_array($val['type'], array('timestamp'))) {
500  $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
501  } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) {
502  $cssforfield .= ($cssforfield ? ' ' : '').'right';
503  }
504  if (!empty($arrayfields['t.'.$key]['checked'])) {
505  print '<td class="liste_titre'.($cssforfield ? ' '.$cssforfield : '').'">';
506  if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
507  print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1);
508  } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) {
509  print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', $cssforfield.' maxwidth250', 1);
510  } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
511  print '<div class="nowrap">';
512  print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
513  print '</div>';
514  print '<div class="nowrap">';
515  print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
516  print '</div>';
517  } elseif ($key == 'lang') {
518  require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
519  $formadmin = new FormAdmin($db);
520  print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth150 maxwidth200', 2);
521  } else {
522  print '<input type="text" class="flat maxwidth75" name="search_'.$key.'" value="'.dol_escape_htmltag(isset($search[$key]) ? $search[$key] : '').'">';
523  }
524  print '</td>';
525  }
526 }
527 // Extra fields
528 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
529 
530 // Fields from hook
531 $parameters = array('arrayfields'=>$arrayfields);
532 $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook
533 print $hookmanager->resPrint;
534 /*if (!empty($arrayfields['anotherfield']['checked'])) {
535  print '<td class="liste_titre"></td>';
536  }*/
537 // Action column
538 if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
539  print '<td class="liste_titre maxwidthsearch">';
540  $searchpicto = $form->showFilterButtons();
541  print $searchpicto;
542  print '</td>';
543 }
544 print '</tr>'."\n";
545 
546 $totalarray = array();
547 $totalarray['nbfield'] = 0;
548 
549 // Fields title label
550 // --------------------------------------------------------------------
551 print '<tr class="liste_titre">';
552 if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
553  print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
554 }
555 foreach ($object->fields as $key => $val) {
556  $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
557  if ($key == 'status') {
558  $cssforfield .= ($cssforfield ? ' ' : '').'center';
559  } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
560  $cssforfield .= ($cssforfield ? ' ' : '').'center';
561  } elseif (in_array($val['type'], array('timestamp'))) {
562  $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
563  } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) {
564  $cssforfield .= ($cssforfield ? ' ' : '').'right';
565  }
566  $cssforfield = preg_replace('/small\s*/', '', $cssforfield); // the 'small' css must not be used for the title label
567  if (!empty($arrayfields['t.'.$key]['checked'])) {
568  print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''))."\n";
569  $totalarray['nbfield']++;
570  }
571 }
572 // Extra fields
573 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
574 // Hook fields
575 $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder, 'totalarray'=>&$totalarray);
576 $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
577 print $hookmanager->resPrint;
578 // Action column
579 if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
580  print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
581 }
582 $totalarray['nbfield']++;
583 print '</tr>'."\n";
584 
585 
586 // Detect if we need a fetch on each output line
587 $needToFetchEachLine = 0;
588 if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) {
589  foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) {
590  if (preg_match('/\$object/', $val)) {
591  $needToFetchEachLine++; // There is at least one compute field that use $object
592  }
593  }
594 }
595 
596 
597 // Loop on record
598 // --------------------------------------------------------------------
599 $i = 0;
600 $savnbfield = $totalarray['nbfield'];
601 $totalarray['nbfield'] = 0;
602 $imaxinloop = ($limit ? min($num, $limit) : $num);
603 while ($i < $imaxinloop) {
604  $obj = $db->fetch_object($resql);
605  if (empty($obj)) {
606  break; // Should not happen
607  }
608 
609  // Store properties in $object
610  $object->setVarsFromFetchObj($obj);
611 
612  // Show here line of result
613  $j = 0;
614  print '<tr data-rowid="'.$object->id.'" class="oddeven">';
615  // Action column
616  if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
617  print '<td class="nowrap center">';
618  if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
619  $selected = 0;
620  if (in_array($object->id, $arrayofselected)) {
621  $selected = 1;
622  }
623  print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
624  }
625  print '</td>';
626  }
627  foreach ($object->fields as $key => $val) {
628  $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
629  if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
630  $cssforfield .= ($cssforfield ? ' ' : '').'center';
631  } elseif ($key == 'status') {
632  $cssforfield .= ($cssforfield ? ' ' : '').'center';
633  }
634 
635  if (in_array($val['type'], array('timestamp'))) {
636  $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
637  } elseif ($key == 'ref' || $key == 'batch') {
638  $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
639  }
640 
641  if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status')) && empty($val['arrayofkeyval'])) {
642  $cssforfield .= ($cssforfield ? ' ' : '').'right';
643  }
644  //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100';
645 
646  if (!empty($arrayfields['t.'.$key]['checked'])) {
647  print '<td'.($cssforfield ? ' class="'.$cssforfield.'"' : '');
648  if (preg_match('/tdoverflow/', $cssforfield)) {
649  print ' title="'.dol_escape_htmltag($object->$key).'"';
650  }
651  print '>';
652  if ($key == 'status') {
653  print $object->getLibStatut(5);
654  } elseif ($key == 'rowid') {
655  print $object->showOutputField($val, $key, $object->id, '');
656  } else {
657  if ($key == 'batch') {
658  print $object->getNomUrl(1);
659  } else {
660  print $object->showOutputField($val, $key, $object->$key, '');
661  }
662  }
663  print '</td>';
664  if (!$i) {
665  $totalarray['nbfield']++;
666  }
667  if (!empty($val['isameasure']) && $val['isameasure'] == 1) {
668  if (!$i) {
669  $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key;
670  }
671  if (!isset($totalarray['val'])) {
672  $totalarray['val'] = array();
673  }
674  if (!isset($totalarray['val']['t.'.$key])) {
675  $totalarray['val']['t.'.$key] = 0;
676  }
677  $totalarray['val']['t.'.$key] += $object->$key;
678  }
679  }
680  }
681  // Extra fields
682  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
683  // Fields from hook
684  $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray);
685  $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook
686  print $hookmanager->resPrint;
687  // Action column
688  if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
689  print '<td class="nowrap center">';
690  if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
691  $selected = 0;
692  if (in_array($object->id, $arrayofselected)) {
693  $selected = 1;
694  }
695  print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
696  }
697  print '</td>';
698  }
699  if (!$i) {
700  $totalarray['nbfield']++;
701  }
702 
703  print '</tr>'."\n";
704 
705  $i++;
706 }
707 
708 // Show total line
709 include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
710 
711 // If no record found
712 if ($num == 0) {
713  $colspan = 1;
714  foreach ($arrayfields as $key => $val) {
715  if (!empty($val['checked'])) {
716  $colspan++;
717  }
718  }
719  print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
720 }
721 
722 
723 $db->free($resql);
724 
725 $parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql);
726 $reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
727 print $hookmanager->resPrint;
728 
729 print '</table>'."\n";
730 print '</div>'."\n";
731 
732 print '</form>'."\n";
733 
734 if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
735  $hidegeneratedfilelistifempty = 1;
736  if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
737  $hidegeneratedfilelistifempty = 0;
738  }
739 
740  require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
741  $formfile = new FormFile($db);
742 
743  // Show list of available documents
744  $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
745  $urlsource .= str_replace('&amp;', '&', $param);
746 
747  $filedir = $diroutputmassaction;
748  $genallowed = $permissiontoread;
749  $delallowed = $permissiontoadd;
750 
751  print $formfile->showdocuments('massfilesarea_mymodule', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
752 }
753 
754 // End of page
755 llxFooter();
756 $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 standard extra fields.
Class to generate html code for admin pages.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class with list of lots and properties.
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_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
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.
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_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.
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.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
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.
$nbtotalofrecords
Count total nb of records.
Definition: list.php:329
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.