dolibarr  19.0.0-dev
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 .= $hookmanager->resPrint;
229 $sql = preg_replace('/,\s*$/', '', $sql);
230 $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
231 if (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); // Note that $action and $object may have been modified by hook
237 $sql .= $hookmanager->resPrint;
238 if ($object->ismultientitymanaged == 1) {
239  $sql .= " WHERE t.entity IN (".getEntity($object->element).")";
240 } else {
241  $sql .= " WHERE 1 = 1";
242 }
243 foreach ($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 if ($search_all) {
273  $sql .= natural_search(array_keys($fieldstosearchall), $search_all);
274 }
275 //$sql.= dolSqlDateFilter("t.field", $search_xxxday, $search_xxxmonth, $search_xxxyear);
276 // Add where from extra fields
277 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
278 // Add where from hooks
279 $parameters = array();
280 $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook
281 $sql .= $hookmanager->resPrint;
282 
283 /* If a group by is required
284 $sql.= " GROUP BY ";
285 foreach($object->fields as $key => $val) {
286  $sql .= "t.".$db->escape($key).", ";
287 }
288 // Add fields from extrafields
289 if (!empty($extrafields->attributes[$object->table_element]['label'])) {
290  foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
291  $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : '');
292  }
293 }
294 // Add where from hooks
295 $parameters=array();
296 $reshook=$hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook
297 $sql.=$hookmanager->resPrint;
298 $sql=preg_replace('/,\s*$/','', $sql);
299 */
300 
301 // Count total nb of records
302 $nbtotalofrecords = '';
303 if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
304  /* This old and fast method to get and count full list returns all record so use a high amount of memory.
305  $resql = $db->query($sql);
306  $nbtotalofrecords = $db->num_rows($resql);
307  */
308  /* The slow method does not consume memory on mysql (not tested on pgsql) */
309  /*$resql = $db->query($sql, 0, 'auto', 1);
310  while ($db->fetch_object($resql)) {
311  if (empty($nbtotalofrecords)) {
312  $nbtotalofrecords = 1; // We can't make +1 because init value is ''
313  } else {
314  $nbtotalofrecords++;
315  }
316  }*/
317  /* The fast and low memory method to get and count full list converts the sql into a sql count */
318  $sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\‍(\‍),=<>\:\-\']+\sFROM/Ui', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql);
319  $resql = $db->query($sqlforcount);
320  if ($resql) {
321  $objforcount = $db->fetch_object($resql);
322  $nbtotalofrecords = $objforcount->nbtotalofrecords;
323  } else {
324  dol_print_error($db);
325  }
326 
327  if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0
328  $page = 0;
329  $offset = 0;
330  }
331  $db->free($resql);
332 }
333 
334 // Complete request and execute it with limit
335 $sql .= $db->order($sortfield, $sortorder);
336 if ($limit) {
337  $sql .= $db->plimit($limit + 1, $offset);
338 }
339 
340 $resql = $db->query($sql);
341 if (!$resql) {
342  dol_print_error($db);
343  exit;
344 }
345 
346 $num = $db->num_rows($resql);
347 
348 $i = 0;
349 
350 // Direct jump if only one record found
351 if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) {
352  $obj = $db->fetch_object($resql);
353  $id = $obj->rowid;
354  header("Location: ".DOL_URL_ROOT.'/product/stock/productlot_card.php?id='.$id);
355  exit;
356 }
357 
358 
359 // Output page
360 // --------------------------------------------------------------------
361 
362 llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'bodyforlist');
363 
364 $arrayofselected = is_array($toselect) ? $toselect : array();
365 
366 $param = '';
367 if (!empty($mode)) {
368  $param .= '&mode='.urlencode($mode);
369 }
370 if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
371  $param .= '&contextpage='.urlencode($contextpage);
372 }
373 if ($limit > 0 && $limit != $conf->liste_limit) {
374  $param .= '&limit='.((int) $limit);
375 }
376 foreach ($search as $key => $val) {
377  if (is_array($search[$key]) && count($search[$key])) {
378  foreach ($search[$key] as $skey) {
379  if ($skey != '') {
380  $param .= '&search_'.$key.'[]='.urlencode($skey);
381  }
382  }
383  } elseif ($search[$key] != '') {
384  $param .= '&search_'.$key.'='.urlencode($search[$key]);
385  }
386 }
387 if ($optioncss != '') {
388  $param .= '&optioncss='.urlencode($optioncss);
389 }
390 // Add $param from extra fields
391 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
392 // Add $param from hooks
393 $parameters = array();
394 $reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook
395 $param .= $hookmanager->resPrint;
396 
397 // List of mass actions available
398 $arrayofmassactions = array(
399  //'validate'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"),
400  //'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"),
401  //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
402  //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
403 );
404 if (!empty($permissiontodelete)) {
405  $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
406 }
407 if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) {
408  $arrayofmassactions = array();
409 }
410 $massactionbutton = $form->selectMassAction('', $arrayofmassactions);
411 
412 print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
413 if ($optioncss != '') {
414  print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
415 }
416 print '<input type="hidden" name="token" value="'.newToken().'">';
417 print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
418 print '<input type="hidden" name="action" value="list">';
419 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
420 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
421 print '<input type="hidden" name="page" value="'.$page.'">';
422 print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
423 print '<input type="hidden" name="mode" value="'.$mode.'">';
424 
425 $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);
426 
427 print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1);
428 
429 // Add code for pre mass action (confirmation or email presend form)
430 $topicmail = "Information";
431 $modelmail = "productlot";
432 $objecttmp = new Productlot($db);
433 $trackid = 'lot'.$object->id;
434 include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
435 
436 if ($search_all) {
437  $setupstring = '';
438  foreach ($fieldstosearchall as $key => $val) {
439  $fieldstosearchall[$key] = $langs->trans($val);
440  $setupstring .= $key."=".$val.";";
441  }
442  print '<!-- Search done like if PRODUCT_QUICKSEARCH_ON_FIELDS = '.$setupstring.' -->'."\n";
443  print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'</div>'."\n";
444 }
445 
446 // Filter on categories
447 $moreforfilter = '';
448 /*$moreforfilter.='<div class="divsearchfield">';
449  $moreforfilter.= $langs->trans('MyFilter') . ': <input type="text" name="search_myfield" value="'.dol_escape_htmltag($search_myfield).'">';
450  $moreforfilter.= '</div>';*/
451 
452 $parameters = array();
453 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
454 if (empty($reshook)) {
455  $moreforfilter .= $hookmanager->resPrint;
456 } else {
457  $moreforfilter = $hookmanager->resPrint;
458 }
459 
460 if (!empty($moreforfilter)) {
461  print '<div class="liste_titre liste_titre_bydiv centpercent">';
462  print $moreforfilter;
463  $parameters = array();
464  $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
465  print $hookmanager->resPrint;
466  print '</div>';
467 }
468 
469 $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
470 $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // This also change content of $arrayfields
471 $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
472 
473 print '<div class="div-table-responsive">';
474 print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
475 
476 
477 // Fields title search
478 // --------------------------------------------------------------------
479 print '<tr class="liste_titre_filter">';
480 // Action column
481 if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
482  print '<td class="liste_titre maxwidthsearch">';
483  $searchpicto = $form->showFilterButtons('left');
484  print $searchpicto;
485  print '</td>';
486 }
487 foreach ($object->fields as $key => $val) {
488  $searchkey = empty($search[$key]) ? '' : $search[$key];
489  $cssforfield = (empty($val['css']) ? '' : $val['css']);
490  if ($key == 'status') {
491  $cssforfield .= ($cssforfield ? ' ' : '').'center';
492  } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
493  $cssforfield .= ($cssforfield ? ' ' : '').'center';
494  } elseif (in_array($val['type'], array('timestamp'))) {
495  $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
496  } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) {
497  $cssforfield .= ($cssforfield ? ' ' : '').'right';
498  }
499  if (!empty($arrayfields['t.'.$key]['checked'])) {
500  print '<td class="liste_titre'.($cssforfield ? ' '.$cssforfield : '').'">';
501  if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
502  print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1);
503  } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) {
504  print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', $cssforfield.' maxwidth250', 1);
505  } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
506  print '<div class="nowrap">';
507  print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
508  print '</div>';
509  print '<div class="nowrap">';
510  print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
511  print '</div>';
512  } elseif ($key == 'lang') {
513  require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
514  $formadmin = new FormAdmin($db);
515  print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth150 maxwidth200', 2);
516  } else {
517  print '<input type="text" class="flat maxwidth75" name="search_'.$key.'" value="'.dol_escape_htmltag(isset($search[$key]) ? $search[$key] : '').'">';
518  }
519  print '</td>';
520  }
521 }
522 // Extra fields
523 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
524 
525 // Fields from hook
526 $parameters = array('arrayfields'=>$arrayfields);
527 $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook
528 print $hookmanager->resPrint;
529 /*if (!empty($arrayfields['anotherfield']['checked'])) {
530  print '<td class="liste_titre"></td>';
531  }*/
532 // Action column
533 if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
534  print '<td class="liste_titre maxwidthsearch">';
535  $searchpicto = $form->showFilterButtons();
536  print $searchpicto;
537  print '</td>';
538 }
539 print '</tr>'."\n";
540 
541 $totalarray = array();
542 $totalarray['nbfield'] = 0;
543 
544 // Fields title label
545 // --------------------------------------------------------------------
546 print '<tr class="liste_titre">';
547 if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
548  print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
549 }
550 foreach ($object->fields as $key => $val) {
551  $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
552  if ($key == 'status') {
553  $cssforfield .= ($cssforfield ? ' ' : '').'center';
554  } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
555  $cssforfield .= ($cssforfield ? ' ' : '').'center';
556  } elseif (in_array($val['type'], array('timestamp'))) {
557  $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
558  } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) {
559  $cssforfield .= ($cssforfield ? ' ' : '').'right';
560  }
561  $cssforfield = preg_replace('/small\s*/', '', $cssforfield); // the 'small' css must not be used for the title label
562  if (!empty($arrayfields['t.'.$key]['checked'])) {
563  print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''))."\n";
564  $totalarray['nbfield']++;
565  }
566 }
567 // Extra fields
568 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
569 // Hook fields
570 $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder, 'totalarray'=>&$totalarray);
571 $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
572 print $hookmanager->resPrint;
573 // Action column
574 if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
575  print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
576 }
577 $totalarray['nbfield']++;
578 print '</tr>'."\n";
579 
580 
581 // Detect if we need a fetch on each output line
582 $needToFetchEachLine = 0;
583 if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) {
584  foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) {
585  if (!is_null($val) && preg_match('/\$object/', $val)) {
586  $needToFetchEachLine++; // There is at least one compute field that use $object
587  }
588  }
589 }
590 
591 
592 // Loop on record
593 // --------------------------------------------------------------------
594 $i = 0;
595 $savnbfield = $totalarray['nbfield'];
596 $totalarray['nbfield'] = 0;
597 $imaxinloop = ($limit ? min($num, $limit) : $num);
598 while ($i < $imaxinloop) {
599  $obj = $db->fetch_object($resql);
600  if (empty($obj)) {
601  break; // Should not happen
602  }
603 
604  // Store properties in $object
605  $object->setVarsFromFetchObj($obj);
606 
607  // Show here line of result
608  $j = 0;
609  print '<tr data-rowid="'.$object->id.'" class="oddeven">';
610  // Action column
611  if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
612  print '<td class="nowrap center">';
613  if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
614  $selected = 0;
615  if (in_array($object->id, $arrayofselected)) {
616  $selected = 1;
617  }
618  print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
619  }
620  print '</td>';
621  }
622  foreach ($object->fields as $key => $val) {
623  $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
624  if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
625  $cssforfield .= ($cssforfield ? ' ' : '').'center';
626  } elseif ($key == 'status') {
627  $cssforfield .= ($cssforfield ? ' ' : '').'center';
628  }
629 
630  if (in_array($val['type'], array('timestamp'))) {
631  $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
632  } elseif ($key == 'ref' || $key == 'batch') {
633  $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
634  }
635 
636  if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status')) && empty($val['arrayofkeyval'])) {
637  $cssforfield .= ($cssforfield ? ' ' : '').'right';
638  }
639  //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100';
640 
641  if (!empty($arrayfields['t.'.$key]['checked'])) {
642  print '<td'.($cssforfield ? ' class="'.$cssforfield.(preg_match('/tdoverflow/', $cssforfield) ? ' classfortooltip' : '').'"' : '');
643  if (preg_match('/tdoverflow/', $cssforfield) && !is_numeric($object->$key)) {
644  print ' title="'.dol_escape_htmltag($object->$key).'"';
645  }
646  print '>';
647  if ($key == 'status') {
648  print $object->getLibStatut(5);
649  } elseif ($key == 'rowid') {
650  print $object->showOutputField($val, $key, $object->id, '');
651  } else {
652  if ($key == 'batch') {
653  print $object->getNomUrl(1);
654  } else {
655  print $object->showOutputField($val, $key, $object->$key, '');
656  }
657  }
658  print '</td>';
659  if (!$i) {
660  $totalarray['nbfield']++;
661  }
662  if (!empty($val['isameasure']) && $val['isameasure'] == 1) {
663  if (!$i) {
664  $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key;
665  }
666  if (!isset($totalarray['val'])) {
667  $totalarray['val'] = array();
668  }
669  if (!isset($totalarray['val']['t.'.$key])) {
670  $totalarray['val']['t.'.$key] = 0;
671  }
672  $totalarray['val']['t.'.$key] += $object->$key;
673  }
674  }
675  }
676  // Extra fields
677  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
678  // Fields from hook
679  $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray);
680  $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook
681  print $hookmanager->resPrint;
682  // Action column
683  if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
684  print '<td class="nowrap center">';
685  if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
686  $selected = 0;
687  if (in_array($object->id, $arrayofselected)) {
688  $selected = 1;
689  }
690  print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
691  }
692  print '</td>';
693  }
694  if (!$i) {
695  $totalarray['nbfield']++;
696  }
697 
698  print '</tr>'."\n";
699 
700  $i++;
701 }
702 
703 // Show total line
704 include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
705 
706 // If no record found
707 if ($num == 0) {
708  $colspan = 1;
709  foreach ($arrayfields as $key => $val) {
710  if (!empty($val['checked'])) {
711  $colspan++;
712  }
713  }
714  print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
715 }
716 
717 
718 $db->free($resql);
719 
720 $parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql);
721 $reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
722 print $hookmanager->resPrint;
723 
724 print '</table>'."\n";
725 print '</div>'."\n";
726 
727 print '</form>'."\n";
728 
729 if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
730  $hidegeneratedfilelistifempty = 1;
731  if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
732  $hidegeneratedfilelistifempty = 0;
733  }
734 
735  require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
736  $formfile = new FormFile($db);
737 
738  // Show list of available documents
739  $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
740  $urlsource .= str_replace('&amp;', '&', $param);
741 
742  $filedir = $diroutputmassaction;
743  $genallowed = $permissiontoread;
744  $delallowed = $permissiontoadd;
745 
746  print $formfile->showdocuments('massfilesarea_mymodule', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
747 }
748 
749 // End of page
750 llxFooter();
751 $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') && $user->hasRight('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') && $user->hasRight('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)) $sql
Social contributions to pay.
Definition: index.php:746
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_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...
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
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.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
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.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getDolGlobalString($key, $default='')
Return 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...
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.