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