dolibarr 18.0.6
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
25require '../main.inc.php';
26require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
27require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
28require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
29require_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');
53if (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)
74if (!$sortfield) {
75 reset($object->fields); // Reset is required to avoid key() to return null.
76 $sortfield = "t.".key($object->fields); // Set here default search field. By default 1st field in definition.
77}
78if (!$sortorder) {
79 $sortorder = "ASC";
80}
81
82// Initialize array of search criterias
83$search_all = GETPOST('search_all', 'alphanohtml');
84$search = array();
85foreach ($object->fields as $key => $val) {
86 if (GETPOST('search_'.$key, 'alpha') !== '') {
87 $search[$key] = GETPOST('search_'.$key, 'alpha');
88 }
89 if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
90 $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, 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();
97foreach ($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();
105foreach ($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
119include 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
129if ($user->socid > 0) {
130 // Protection if external user
132}
133$result = restrictedArea($user, 'bom');
134
135
136/*
137 * Actions
138 */
139
140if (GETPOST('cancel', 'alpha')) {
141 $action = 'list';
142 $massaction = '';
143}
144if (!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
150if ($reshook < 0) {
151 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
152}
153
154if (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
301if (!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";
315if (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;
322if ($object->ismultientitymanaged == 1) {
323 $sql .= " WHERE t.entity IN (".getEntity($object->element).")";
324} else {
325 $sql .= " WHERE 1 = 1";
326}
327foreach ($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
357if ($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
362include 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 ";
370foreach($object->fields as $key => $val) {
371 $sql .= "t.".$db->escape($key).", ";
372}
373// Add fields from extrafields
374if (!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 = '';
388if (!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);
409if ($limit) {
410 $sql .= $db->plimit($limit + 1, $offset);
411}
412
413$resql = $db->query($sql);
414if (!$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
422if ($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
433llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', '');
434
435$arrayofselected = is_array($toselect) ? $toselect : array();
436
437$param = '';
438if (!empty($mode)) {
439 $param .= '&mode='.urlencode($mode);
440}
441if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
442 $param .= '&contextpage='.urlencode($contextpage);
443}
444if ($limit > 0 && $limit != $conf->liste_limit) {
445 $param .= '&limit='.((int) $limit);
446}
447foreach ($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}
462if ($optioncss != '') {
463 $param .= '&optioncss='.urlencode($optioncss);
464}
465// Add $param from extra fields
466include 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);
478if (!empty($permissiontodelete)) {
479 $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
480}
481if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) {
482 $arrayofmassactions = array();
483}
484$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
485
486print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
487if ($optioncss != '') {
488 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
489}
490print '<input type="hidden" name="token" value="'.newToken().'">';
491print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
492print '<input type="hidden" name="action" value="list">';
493print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
494print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
495print '<input type="hidden" name="page" value="'.$page.'">';
496print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
497print '<input type="hidden" name="page_y" value="">';
498print '<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
505print_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;
512include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
513
514if ($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
531if (empty($reshook)) {
532 $moreforfilter .= $hookmanager->resPrint;
533} else {
534 $moreforfilter = $hookmanager->resPrint;
535}
536
537if (!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
547print '<div class="div-table-responsive">';
548print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
549
550
551// Fields title search
552// --------------------------------------------------------------------
553print '<tr class="liste_titre">';
554
555// Action column
556if (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
563foreach ($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
601include 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
606print $hookmanager->resPrint;
607// Action column
608if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
609 print '<td class="liste_titre maxwidthsearch">';
610 $searchpicto = $form->showFilterButtons();
611 print $searchpicto;
612 print '</td>';
613}
614print '</tr>'."\n";
615
616$totalarray = array();
617$totalarray['nbfield'] = 0;
618
619// Fields title label
620// --------------------------------------------------------------------
621print '<tr class="liste_titre">';
622// Action column
623if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
624 print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
625}
626foreach ($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
644include 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
648print $hookmanager->resPrint;
649// Action column
650if (!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
654print '</tr>'."\n";
655
656
657// Detect if we need a fetch on each output line
658$needToFetchEachLine = 0;
659if (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);
675while ($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
790include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
791
792
793// If no record found
794if ($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
809print $hookmanager->resPrint;
810
811print '</table>'."\n";
812print '</div>'."\n";
813
814print '</form>'."\n";
815
816
817if (in_array('builddoc', array_keys($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
838llxFooter();
839$db->close();
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:39
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.
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.
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.