dolibarr 19.0.3
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
28require '../../main.inc.php';
29require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
30require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
31require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
32require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
33require_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');
60if (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)
81if (!$sortfield) {
82 $sortfield = "t.fk_product,t.batch"; // Set here default search field. By default 1st field in definition.
83}
84if (!$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();
91foreach ($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();
103foreach ($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();
111foreach ($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
125include 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
141if (empty($conf->productbatch->enabled)) {
142 accessforbidden('Module not enabled');
143}
144$socid = 0;
145if ($user->socid > 0) { // Protection if external user
146 //$socid = $user->socid;
148}
149//$result = restrictedArea($user, 'productbatch');
150if (!$permissiontoread) {
152}
153
154
155/*
156 * Actions
157 */
158
159if (GETPOST('cancel', 'alpha')) {
160 $action = 'list';
161 $massaction = '';
162}
163if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
164 $massaction = '';
165}
166
167$parameters = array();
168$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
169if ($reshook < 0) {
170 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
171}
172
173if (empty($reshook)) {
174 // Selection of new fields
175 include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
176
177 // Purge search criteria
178 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
179 foreach ($object->fields as $key => $val) {
180 $search[$key] = '';
181 if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
182 $search[$key.'_dtstart'] = '';
183 $search[$key.'_dtend'] = '';
184 }
185 }
186 $toselect = array();
187 $search_array_options = array();
188 }
189 if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
190 || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
191 $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
192 }
193
194 // Mass actions
195 $objectclass = 'ProductLot';
196 $objectlabel = 'LotSerial';
197 $uploaddir = $conf->productbatch->dir_output;
198 include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
199}
200
201
202/*
203 * View
204 */
205
206
207$form = new Form($db);
208
209$now = dol_now();
210
211$help_url = 'EN:Module_Lot_/_Serial|FR:Module_Lot_/_Série';
212$title = $langs->trans('LotSerialList');
213$morejs = array();
214$morecss = array();
215
216
217// Build and execute select
218// --------------------------------------------------------------------
219$sql = 'SELECT ';
220$sql .= $object->getFieldList('t');
221// Add fields from extrafields
222if (!empty($extrafields->attributes[$object->table_element]['label'])) {
223 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
224 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
225 }
226}
227// Add fields from hooks
228$parameters = array();
229$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
230$sql .= $hookmanager->resPrint;
231$sql = preg_replace('/,\s*$/', '', $sql);
232
233$sqlfields = $sql;
234
235$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
236if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
237 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)";
238}
239// Add table from hooks
240$parameters = array();
241$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook
242$sql .= $hookmanager->resPrint;
243if ($object->ismultientitymanaged == 1) {
244 $sql .= " WHERE t.entity IN (".getEntity($object->element).")";
245} else {
246 $sql .= " WHERE 1 = 1";
247}
248foreach ($search as $key => $val) {
249 if (array_key_exists($key, $object->fields)) {
250 if ($key == 'status' && $search[$key] == -1) {
251 continue;
252 }
253 $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0);
254 if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) {
255 if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) {
256 $search[$key] = '';
257 }
258 $mode_search = 2;
259 }
260 if ($search[$key] != '') {
261 $sql .= natural_search("t.".$db->escape($key), $search[$key], (($key == 'status') ? 2 : $mode_search));
262 }
263 } else {
264 if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') {
265 $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key);
266 if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) {
267 if (preg_match('/_dtstart$/', $key)) {
268 $sql .= " AND t.".$db->escape($columnName)." >= '".$db->idate($search[$key])."'";
269 }
270 if (preg_match('/_dtend$/', $key)) {
271 $sql .= " AND t.".$db->escape($columnName)." <= '".$db->idate($search[$key])."'";
272 }
273 }
274 }
275 }
276}
277if ($search_all) {
278 $sql .= natural_search(array_keys($fieldstosearchall), $search_all);
279}
280//$sql.= dolSqlDateFilter("t.field", $search_xxxday, $search_xxxmonth, $search_xxxyear);
281// Add where from extra fields
282include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
283// Add where from hooks
284$parameters = array();
285$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook
286$sql .= $hookmanager->resPrint;
287
288/* If a group by is required
289$sql.= " GROUP BY ";
290foreach($object->fields as $key => $val) {
291 $sql .= "t.".$db->escape($key).", ";
292}
293// Add fields from extrafields
294if (!empty($extrafields->attributes[$object->table_element]['label'])) {
295 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
296 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : '');
297 }
298}
299// Add where from hooks
300$parameters=array();
301$reshook=$hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook
302$sql.=$hookmanager->resPrint;
303$sql=preg_replace('/,\s*$/','', $sql);
304*/
305
306// Count total nb of records
307$nbtotalofrecords = '';
308if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
309 /* This old and fast method to get and count full list returns all record so use a high amount of memory.
310 $resql = $db->query($sql);
311 $nbtotalofrecords = $db->num_rows($resql);
312 */
313 /* The slow method does not consume memory on mysql (not tested on pgsql) */
314 /*$resql = $db->query($sql, 0, 'auto', 1);
315 while ($db->fetch_object($resql)) {
316 if (empty($nbtotalofrecords)) {
317 $nbtotalofrecords = 1; // We can't make +1 because init value is ''
318 } else {
319 $nbtotalofrecords++;
320 }
321 }*/
322 /* The fast and low memory method to get and count full list converts the sql into a sql count */
323 $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
324 $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
325
326 $resql = $db->query($sqlforcount);
327 if ($resql) {
328 $objforcount = $db->fetch_object($resql);
329 $nbtotalofrecords = $objforcount->nbtotalofrecords;
330 } else {
331 dol_print_error($db);
332 }
333
334 if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0
335 $page = 0;
336 $offset = 0;
337 }
338 $db->free($resql);
339}
340
341// Complete request and execute it with limit
342$sql .= $db->order($sortfield, $sortorder);
343if ($limit) {
344 $sql .= $db->plimit($limit + 1, $offset);
345}
346
347$resql = $db->query($sql);
348if (!$resql) {
349 dol_print_error($db);
350 exit;
351}
352
353$num = $db->num_rows($resql);
354
355$i = 0;
356
357// Direct jump if only one record found
358if ($num == 1 && getDolGlobalString('MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE') && $search_all && !$page) {
359 $obj = $db->fetch_object($resql);
360 $id = $obj->rowid;
361 header("Location: ".DOL_URL_ROOT.'/product/stock/productlot_card.php?id='.$id);
362 exit;
363}
364
365
366// Output page
367// --------------------------------------------------------------------
368
369llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'bodyforlist');
370
371$arrayofselected = is_array($toselect) ? $toselect : array();
372
373$param = '';
374if (!empty($mode)) {
375 $param .= '&mode='.urlencode($mode);
376}
377if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
378 $param .= '&contextpage='.urlencode($contextpage);
379}
380if ($limit > 0 && $limit != $conf->liste_limit) {
381 $param .= '&limit='.((int) $limit);
382}
383foreach ($search as $key => $val) {
384 if (is_array($search[$key]) && count($search[$key])) {
385 foreach ($search[$key] as $skey) {
386 if ($skey != '') {
387 $param .= '&search_'.$key.'[]='.urlencode($skey);
388 }
389 }
390 } elseif ($search[$key] != '') {
391 $param .= '&search_'.$key.'='.urlencode($search[$key]);
392 }
393}
394if ($optioncss != '') {
395 $param .= '&optioncss='.urlencode($optioncss);
396}
397// Add $param from extra fields
398include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
399// Add $param from hooks
400$parameters = array('param' => &$param);
401$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook
402$param .= $hookmanager->resPrint;
403
404// List of mass actions available
405$arrayofmassactions = array(
406 //'validate'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"),
407 //'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"),
408 //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
409 //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
410);
411if (!empty($permissiontodelete)) {
412 $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
413}
414if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) {
415 $arrayofmassactions = array();
416}
417$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
418
419print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
420if ($optioncss != '') {
421 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
422}
423print '<input type="hidden" name="token" value="'.newToken().'">';
424print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
425print '<input type="hidden" name="action" value="list">';
426print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
427print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
428print '<input type="hidden" name="page" value="'.$page.'">';
429print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
430print '<input type="hidden" name="mode" value="'.$mode.'">';
431
432$newcardbutton = '';
433$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);
434
435print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1);
436
437// Add code for pre mass action (confirmation or email presend form)
438$topicmail = "Information";
439$modelmail = "productlot";
440$objecttmp = new Productlot($db);
441$trackid = 'lot'.$object->id;
442include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
443
444if ($search_all) {
445 $setupstring = '';
446 foreach ($fieldstosearchall as $key => $val) {
447 $fieldstosearchall[$key] = $langs->trans($val);
448 $setupstring .= $key."=".$val.";";
449 }
450 print '<!-- Search done like if PRODUCT_QUICKSEARCH_ON_FIELDS = '.$setupstring.' -->'."\n";
451 print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'</div>'."\n";
452}
453
454// Filter on categories
455$moreforfilter = '';
456/*$moreforfilter.='<div class="divsearchfield">';
457 $moreforfilter.= $langs->trans('MyFilter') . ': <input type="text" name="search_myfield" value="'.dol_escape_htmltag($search_myfield).'">';
458 $moreforfilter.= '</div>';*/
459
460$parameters = array();
461$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
462if (empty($reshook)) {
463 $moreforfilter .= $hookmanager->resPrint;
464} else {
465 $moreforfilter = $hookmanager->resPrint;
466}
467
468if (!empty($moreforfilter)) {
469 print '<div class="liste_titre liste_titre_bydiv centpercent">';
470 print $moreforfilter;
471 $parameters = array();
472 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
473 print $hookmanager->resPrint;
474 print '</div>';
475}
476
477$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
478$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // This also change content of $arrayfields
479$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
480
481print '<div class="div-table-responsive">';
482print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
483
484
485// Fields title search
486// --------------------------------------------------------------------
487print '<tr class="liste_titre_filter">';
488// Action column
489if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
490 print '<td class="liste_titre maxwidthsearch">';
491 $searchpicto = $form->showFilterButtons('left');
492 print $searchpicto;
493 print '</td>';
494}
495foreach ($object->fields as $key => $val) {
496 $searchkey = empty($search[$key]) ? '' : $search[$key];
497 $cssforfield = (empty($val['css']) ? '' : $val['css']);
498 if ($key == 'status') {
499 $cssforfield .= ($cssforfield ? ' ' : '').'center';
500 } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
501 $cssforfield .= ($cssforfield ? ' ' : '').'center';
502 } elseif (in_array($val['type'], array('timestamp'))) {
503 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
504 } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) {
505 $cssforfield .= ($cssforfield ? ' ' : '').'right';
506 }
507 if (!empty($arrayfields['t.'.$key]['checked'])) {
508 print '<td class="liste_titre'.($cssforfield ? ' '.$cssforfield : '').'">';
509 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
510 print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1);
511 } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) {
512 print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', $cssforfield.' maxwidth250', 1);
513 } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
514 print '<div class="nowrap">';
515 print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
516 print '</div>';
517 print '<div class="nowrap">';
518 print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
519 print '</div>';
520 } elseif ($key == 'lang') {
521 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
522 $formadmin = new FormAdmin($db);
523 print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth150 maxwidth200', 2);
524 } else {
525 print '<input type="text" class="flat maxwidth75" name="search_'.$key.'" value="'.dol_escape_htmltag(isset($search[$key]) ? $search[$key] : '').'">';
526 }
527 print '</td>';
528 }
529}
530// Extra fields
531include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
532
533// Fields from hook
534$parameters = array('arrayfields'=>$arrayfields);
535$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook
536print $hookmanager->resPrint;
537/*if (!empty($arrayfields['anotherfield']['checked'])) {
538 print '<td class="liste_titre"></td>';
539 }*/
540// Action column
541if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
542 print '<td class="liste_titre maxwidthsearch">';
543 $searchpicto = $form->showFilterButtons();
544 print $searchpicto;
545 print '</td>';
546}
547print '</tr>'."\n";
548
549$totalarray = array();
550$totalarray['nbfield'] = 0;
551
552// Fields title label
553// --------------------------------------------------------------------
554print '<tr class="liste_titre">';
555if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
556 print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
557}
558foreach ($object->fields as $key => $val) {
559 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
560 if ($key == 'status') {
561 $cssforfield .= ($cssforfield ? ' ' : '').'center';
562 } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
563 $cssforfield .= ($cssforfield ? ' ' : '').'center';
564 } elseif (in_array($val['type'], array('timestamp'))) {
565 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
566 } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) {
567 $cssforfield .= ($cssforfield ? ' ' : '').'right';
568 }
569 $cssforfield = preg_replace('/small\s*/', '', $cssforfield); // the 'small' css must not be used for the title label
570 if (!empty($arrayfields['t.'.$key]['checked'])) {
571 print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''))."\n";
572 $totalarray['nbfield']++;
573 }
574}
575// Extra fields
576include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
577// Hook fields
578$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder, 'totalarray'=>&$totalarray);
579$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
580print $hookmanager->resPrint;
581// Action column
582if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
583 print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
584}
585$totalarray['nbfield']++;
586print '</tr>'."\n";
587
588
589// Detect if we need a fetch on each output line
590$needToFetchEachLine = 0;
591if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) {
592 foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) {
593 if (!is_null($val) && preg_match('/\$object/', $val)) {
594 $needToFetchEachLine++; // There is at least one compute field that use $object
595 }
596 }
597}
598
599
600// Loop on record
601// --------------------------------------------------------------------
602$i = 0;
603$savnbfield = $totalarray['nbfield'];
604$totalarray['nbfield'] = 0;
605$imaxinloop = ($limit ? min($num, $limit) : $num);
606while ($i < $imaxinloop) {
607 $obj = $db->fetch_object($resql);
608 if (empty($obj)) {
609 break; // Should not happen
610 }
611
612 // Store properties in $object
613 $object->setVarsFromFetchObj($obj);
614
615 // Show here line of result
616 $j = 0;
617 print '<tr data-rowid="'.$object->id.'" class="oddeven">';
618 // Action column
619 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
620 print '<td class="nowrap center">';
621 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
622 $selected = 0;
623 if (in_array($object->id, $arrayofselected)) {
624 $selected = 1;
625 }
626 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
627 }
628 print '</td>';
629 }
630 foreach ($object->fields as $key => $val) {
631 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
632 if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
633 $cssforfield .= ($cssforfield ? ' ' : '').'center';
634 } elseif ($key == 'status') {
635 $cssforfield .= ($cssforfield ? ' ' : '').'center';
636 }
637
638 if (in_array($val['type'], array('timestamp'))) {
639 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
640 } elseif ($key == 'ref' || $key == 'batch') {
641 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
642 }
643
644 if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status')) && empty($val['arrayofkeyval'])) {
645 $cssforfield .= ($cssforfield ? ' ' : '').'right';
646 }
647 //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100';
648
649 if (!empty($arrayfields['t.'.$key]['checked'])) {
650 print '<td'.($cssforfield ? ' class="'.$cssforfield.(preg_match('/tdoverflow/', $cssforfield) ? ' classfortooltip' : '').'"' : '');
651 if (preg_match('/tdoverflow/', $cssforfield) && !is_numeric($object->$key)) {
652 print ' title="'.dol_escape_htmltag($object->$key).'"';
653 }
654 print '>';
655 if ($key == 'status') {
656 print $object->getLibStatut(5);
657 } elseif ($key == 'rowid') {
658 print $object->showOutputField($val, $key, $object->id, '');
659 } else {
660 if ($key == 'batch') {
661 print $object->getNomUrl(1);
662 } else {
663 print $object->showOutputField($val, $key, $object->$key, '');
664 }
665 }
666 print '</td>';
667 if (!$i) {
668 $totalarray['nbfield']++;
669 }
670 if (!empty($val['isameasure']) && $val['isameasure'] == 1) {
671 if (!$i) {
672 $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key;
673 }
674 if (!isset($totalarray['val'])) {
675 $totalarray['val'] = array();
676 }
677 if (!isset($totalarray['val']['t.'.$key])) {
678 $totalarray['val']['t.'.$key] = 0;
679 }
680 $totalarray['val']['t.'.$key] += $object->$key;
681 }
682 }
683 }
684 // Extra fields
685 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
686 // Fields from hook
687 $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray);
688 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook
689 print $hookmanager->resPrint;
690 // Action column
691 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
692 print '<td class="nowrap center">';
693 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
694 $selected = 0;
695 if (in_array($object->id, $arrayofselected)) {
696 $selected = 1;
697 }
698 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
699 }
700 print '</td>';
701 }
702 if (!$i) {
703 $totalarray['nbfield']++;
704 }
705
706 print '</tr>'."\n";
707
708 $i++;
709}
710
711// Show total line
712include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
713
714// If no record found
715if ($num == 0) {
716 $colspan = 1;
717 foreach ($arrayfields as $key => $val) {
718 if (!empty($val['checked'])) {
719 $colspan++;
720 }
721 }
722 print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
723}
724
725
726$db->free($resql);
727
728$parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql);
729$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
730print $hookmanager->resPrint;
731
732print '</table>'."\n";
733print '</div>'."\n";
734
735print '</form>'."\n";
736
737if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
738 $hidegeneratedfilelistifempty = 1;
739 if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
740 $hidegeneratedfilelistifempty = 0;
741 }
742
743 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
744 $formfile = new FormFile($db);
745
746 // Show list of available documents
747 $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
748 $urlsource .= str_replace('&amp;', '&', $param);
749
750 $filedir = $diroutputmassaction;
751 $genallowed = $permissiontoread;
752 $delallowed = $permissiontoadd;
753
754 print $formfile->showdocuments('massfilesarea_mymodule', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
755}
756
757// End of page
758llxFooter();
759$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:55
llxFooter()
Empty footer.
Definition wrapper.php:69
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.
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 a 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.
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.