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