dolibarr 25.0.0-alpha
mo_list.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2007-2017 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
4 * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
5 * Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
27// Load Dolibarr environment
28require '../main.inc.php';
37require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
38require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
39require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
40require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
41require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
42// load mrp libraries
43require_once __DIR__.'/class/mo.class.php';
44if (isModEnabled('category')) {
45 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
46 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcategory.class.php';
47}
48
49// Load translation files required by the page
50$langs->loadLangs(array("mrp", "other"));
51
52// Get parameters
53$action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ...
54$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
55$show_files = GETPOSTINT('show_files'); // Show files area generated by bulk actions ?
56$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation
57$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button
58$toselect = GETPOST('toselect', 'array:int'); // Array of ids of elements selected into a list
59$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
60$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
61$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
62$mode = GETPOST('mode', 'alpha');
63$groupby = GETPOST('groupby', 'aZ09'); // Example: $groupby = 'p.fk_opp_status' or $groupby = 'p.fk_statut'
64
65$id = GETPOSTINT('id');
66
67// Load variable for pagination
68$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
69$sortfield = GETPOST('sortfield', 'aZ09comma');
70$sortorder = GETPOST('sortorder', 'aZ09comma');
71$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT('page');
72$also_cancel_consumed_and_produced_lines = (GETPOST('alsoCancelConsumedAndProducedLines', 'alpha') ? 1 : 0);
73$changeDate = GETPOST('change_date', 'alpha');
74
75//Data request for date
76$year = GETPOST('change_dateyear', 'int');
77$month = GETPOST('change_datemonth', 'int');
78$day = GETPOST('change_dateday', 'int');
79$hour = GETPOST('change_datehour', 'int');
80$min = GETPOST('change_datemin', 'int');
81
82if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
83 // If $page is not defined, or '' or -1 or if we click on clear filters
84 $page = 0;
85}
86$offset = $limit * $page;
87$pageprev = $page - 1;
88$pagenext = $page + 1;
89//if (! $sortfield) $sortfield="p.date_fin";
90//if (! $sortorder) $sortorder="DESC";
91
92// Initialize a technical objects
93$object = new Mo($db);
94$diroutputmassaction = $conf->mrp->dir_output.'/temp/massgeneration/'.$user->id;
95$hookmanager->initHooks(array($contextpage)); // Note that conf->hooks_modules contains array of activated contexes
96
97// Fetch optionals attributes and labels
98$extrafields->fetch_name_optionals_label($object->table_element);
99
100$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
101
102$search_option = GETPOST('search_option', 'alphanohtml');
103
104// Default sort order (if not yet defined by previous GETPOST)
105if (!$sortfield) {
106 $sortfield = "t.ref"; // Set here default search field. By default 1st field in definition.
107}
108if (!$sortorder) {
109 $sortorder = "ASC";
110}
111
112// Initialize array of search criteria
113$search_all = trim(GETPOST('search_all', 'alphanohtml'));
114$searchCategoryMoOperator = 0;
115if (GETPOSTISSET('formfilteraction')) {
116 $searchCategoryMoOperator = GETPOSTINT('search_category_mo_operator');
117} elseif (getDolGlobalString('MAIN_SEARCH_CAT_OR_BY_DEFAULT')) {
118 $searchCategoryMoOperator = getDolGlobalString('MAIN_SEARCH_CAT_OR_BY_DEFAULT');
119}
120$searchCategoryMoList = GETPOST('search_category_mo_list', 'array:int');
121$search = array();
122foreach ($object->fields as $key => $val) {
123 if ($key == 'status' && GETPOSTISSET('search_status')) {
124 $search_status = GETPOST('search_status', 'array:int');
125 if (empty($search_status) && GETPOST('search_status', 'alpha') !== '') {
126 $search_status = GETPOST('search_status', 'int');
127 if ($search_status !== -1) {
128 $search_status = array($search_status);
129 } else {
130 $search_status = '';
131 }
132 }
133 $search[$key] = $search_status;
134 } elseif (GETPOST('search_'.$key, 'alpha') !== '') {
135 $search[$key] = GETPOST('search_'.$key, 'alpha');
136 }
137 if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
138 $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOSTINT('search_'.$key.'_dtstartmonth'), GETPOSTINT('search_'.$key.'_dtstartday'), GETPOSTINT('search_'.$key.'_dtstartyear'));
139 $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOSTINT('search_'.$key.'_dtendmonth'), GETPOSTINT('search_'.$key.'_dtendday'), GETPOSTINT('search_'.$key.'_dtendyear'));
140 }
141}
142// List of fields to search into when doing a "search in all"
143$fieldstosearchall = array();
144foreach ($object->fields as $key => $val) {
145 if (!empty($val['searchall'])) {
146 $fieldstosearchall['t.'.$key] = $val['label'];
147 }
148}
149
150// Definition of array of fields for columns
151$tableprefix = 't';
152$arrayfields = array();
153foreach ($object->fields as $key => $val) {
154 // If $val['visible']==0, then we never show the field
155 if (!empty($val['visible'])) {
156 $visible = (int) dol_eval((string) $val['visible'], 1);
157 $arrayfields[$tableprefix.'.'.$key] = array(
158 'label' => $val['label'],
159 'checked' => (($visible < 0) ? '0' : '1'),
160 'enabled' => (string) (int) (abs($visible) != 3 && (bool) dol_eval((string) $val['enabled'], 1)),
161 'position' => $val['position'],
162 'help' => isset($val['help']) ? $val['help'] : ''
163 );
164 }
165
166 if ($key == 'fk_parent_line') {
167 $visible = (int) dol_eval((string) $val['visible'], 1);
168 $arrayfields[$tableprefix.'.'.$key] = array(
169 'label' => $val['label'],
170 'checked' => (($visible <= 0) ? 0 : 1),
171 'enabled' => (abs($visible) != 3 && (bool) dol_eval((string) $val['enabled'], 1)),
172 'position' => $val['position'],
173 'help' => isset($val['help']) ? $val['help'] : ''
174 );
175 }
176}
177// Extra fields
178include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
179// Add hook to complete $arrayfield
180$parameters = array('arrayfields' => &$arrayfields);
181$reshook = $hookmanager->executeHooks('completeArrayFields', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
182
183$object->fields = dol_sort_array($object->fields, 'position');
184$arrayfields = dol_sort_array($arrayfields, 'position');
185
186$permissiontoread = $user->hasRight('mrp', 'read');
187$permissiontoadd = $user->hasRight('mrp', 'write');
188$permissiontodelete = $user->hasRight('mrp', 'delete');
189
190// Security check
191if ($user->socid > 0) {
193}
194$result = restrictedArea($user, 'mrp');
195
196
197/*
198 * Actions
199 */
200
201if (GETPOST('cancel', 'alpha')) {
202 $action = 'list';
203 $massaction = '';
204}
205if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
206 $massaction = '';
207}
208
209$parameters = array('arrayfields' => &$arrayfields);
210$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
211if ($reshook < 0) {
212 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
213}
214
215if (empty($reshook)) {
216 // Selection of new fields
217 include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
218
219 // Purge search criteria
220 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
221 foreach ($object->fields as $key => $val) {
222 $search[$key] = '';
223 if ($key == 'status') {
224 $search[$key] = -1;
225 }
226 if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
227 $search[$key.'_dtstart'] = '';
228 $search[$key.'_dtend'] = '';
229 }
230 }
231 $search_all = '';
232 $searchCategoryMoOperator = 0;
233 $searchCategoryMoList = array();
234 $toselect = array();
235 $search_array_options = array();
236 }
237 if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
238 || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
239 $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
240 }
241
242 // Mass actions
243 $objectclass = 'Mo';
244 $objectlabel = 'Mo';
245 $uploaddir = $conf->mrp->dir_output;
246 include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
247 $objMo = new Mo($db);
248
249 if ($action == 'confirm_cancel' && $confirm == 'yes' && $permissiontoadd) {
250 if (!empty($toselect)) {
251 foreach ($toselect as $key => $idMo) {
252 if ($objMo->fetch($idMo)) {
253 if ($objMo->status == Mo::STATUS_VALIDATED || $objMo->status == Mo::STATUS_INPROGRESS) {
254 if ($also_cancel_consumed_and_produced_lines) {
255 if ($objMo->cancelConsumedAndProducedLines($user, 0, true, 1)) {
256 $objMo->status = Mo::STATUS_CANCELED;
257 }
258 } else {
259 $objMo->status = Mo::STATUS_CANCELED;
260 }
261 if ($objMo->update($user)) {
262 setEventMessages($langs->trans('CancelMoValidated', $objMo->ref), null, 'mesgs');
263 } else {
264 setEventMessages($langs->trans('ErrorCancelMo', $objMo->ref), null, 'errors');
265 }
266 } else {
267 setEventMessages($langs->trans('ErrorObjectMustHaveStatusValidatedToBeCanceled', $objMo->ref), null, 'errors');
268 }
269 }
270 }
271 }
272 }
273
274 if (($action == 'changedatestart_confirm' || $action == 'changedateend_confirm') && $permissiontoadd) {
275 if ($confirm == 'yes') {
276 $newDate = dol_mktime((int) $hour, (int) $min, (int) 0, (int) $month, (int) $day, (int) $year);
277
278 if (!empty($toselect)) {
279 foreach ($toselect as $key => $idMo) {
280 if ($objMo->fetch($idMo)) {
281 if (in_array($action, array('changedatestart_confirm', 'changedateend_confirm'), true) && $objMo->status == Mo::STATUS_PRODUCED) {
282 $errorKey = $action == 'changedatestart_confirm'
283 ? 'ErrorObjectMustNotBeFinishedToModifyDateStart'
284 : 'ErrorObjectMustNotBeFinishedToModifyDateEnd';
285 setEventMessages($langs->trans($errorKey, $objMo->ref), null, 'errors');
286 continue;
287 }
288 if (!empty($changeDate)) {
289 if ($action == 'changedatestart_confirm') { // Test on permission not required
290 // The start date can be set IF (the end date is empty OR the new date is BEFORE the existing end date).
291 if (empty($objMo->date_end_planned) || $newDate < $objMo->date_end_planned) {
292 $objMo->date_start_planned = $newDate;
293 } else {
294 setEventMessages($langs->trans('ErrorModifyMoDateStart', $objMo->ref), null, 'errors');
295 break;
296 }
297 } elseif ($action == 'changedateend_confirm') { // Test on permission not required
298 // The end date can be set IF (the start date is empty OR the new date is AFTER the existing start date).
299 if (empty($objMo->date_start_planned) || $newDate > $objMo->date_start_planned) {
300 $objMo->date_end_planned = $newDate;
301 } else {
302 setEventMessages($langs->trans('ErrorModifyMoDateEnd', $objMo->ref), null, 'errors');
303 break;
304 }
305 }
306 if ($objMo->update($user)) {
307 setEventMessages($langs->trans('ModifyMoDate', $objMo->ref), null, 'mesgs');
308 } else {
309 setEventMessages($langs->trans('ErrorModifyMoDate', $objMo->ref), null, 'errors');
310 }
311 } else {
312 setEventMessages($langs->trans('ErrorEmptyChangeDate'), null, 'errors');
313 break;
314 }
315 }
316 }
317 }
318 }
319 }
320}
321
322
323
324/*
325 * View
326 */
327
328$form = new Form($db);
329
330$now = dol_now();
331
332$help_url = 'EN:Module_Manufacturing_Orders|FR:Module_Ordres_de_Fabrication|DE:Modul_Fertigungsauftrag';
333$title = $langs->trans('ListOfManufacturingOrders');
334$morejs = array();
335$morecss = array();
336
337
338// Build and execute select
339// --------------------------------------------------------------------
340$sql = "SELECT ";
341$sql .= " ".$object->getFieldList('t');
342// Add fields from extrafields
343if (!empty($extrafields->attributes[$object->table_element]['label'])) {
344 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
345 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : "");
346 }
347}
348// Add fields from hooks
349$parameters = array();
350$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
351$sql .= $hookmanager->resPrint;
352$sql = preg_replace('/,\s*$/', '', $sql);
353
354$sqlfields = $sql; // $sql fields to remove for count total
355
356$sql .= " FROM ".$db->prefix().$object->table_element." as t";
357if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
358 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)";
359}
360$sql .= " LEFT JOIN ".$db->prefix()."mrp_production as lineparent ON t.fk_parent_line = lineparent.rowid";
361$sql .= " LEFT JOIN ".$db->prefix()."mrp_mo as moparent ON lineparent.fk_mo = moparent.rowid";
362$sql .= " LEFT JOIN ".$db->prefix()."product as p ON t.fk_product = p.rowid";
363// Add table from hooks
364$parameters = array();
365$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
366$sql .= $hookmanager->resPrint;
367if ($object->ismultientitymanaged == 1) {
368 $sql .= " WHERE t.entity IN (".getEntity($object->element, (GETPOSTINT('search_current_entity') ? 0 : 1)).")";
369} else {
370 $sql .= " WHERE 1 = 1";
371}
372
373foreach ($search as $key => $val) {
374 if (array_key_exists($key, $object->fields)) {
375 if ($key == 'status') {
376 if ($search[$key] === -1 || (is_array($search[$key]) && (count($search[$key]) == 0 || (count($search[$key]) == 1 && reset($search[$key]) == -1)))) {
377 continue;
378 }
379
380 $status_to_search = array();
381 if (is_array($search[$key])) {
382 foreach ($search[$key] as $status_val) {
383 if ($status_val == -2) {
384 $status_to_search[] = $object::STATUS_VALIDATED;
385 $status_to_search[] = $object::STATUS_INPROGRESS;
386 } elseif ($status_val !== '' && $status_val >= 0) {
387 $status_to_search[] = $status_val;
388 }
389 }
390 } elseif ($search[$key] == -2) {
391 $status_to_search[] = $object::STATUS_VALIDATED;
392 $status_to_search[] = $object::STATUS_INPROGRESS;
393 } elseif ($search[$key] !== '' && $search[$key] >= 0) {
394 $status_to_search[] = $search[$key];
395 }
396
397 if (!empty($status_to_search)) {
398 $sql .= " AND t.status IN (".$db->sanitize(implode(',', array_unique($status_to_search))).")";
399 }
400
401 if ($search_option == 'late' && (in_array(-2, (array) $search[$key]) || in_array($object::STATUS_VALIDATED, (array) $search[$key]) || in_array($object::STATUS_INPROGRESS, (array) $search[$key]))) {
402 $sql .= " AND (t.date_end_planned < '".$db->idate(dol_now() - getWarningDelay('mrp', 'progress'))."')";
403 }
404 continue;
405 }
406
407 if ($key == 'fk_parent_line' && $search[$key] != '') {
408 $sql .= natural_search('moparent.ref', $search[$key], 0);
409 continue;
410 }
411
412 $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0);
413 if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) {
414 if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) {
415 $search[$key] = '';
416 }
417 $mode_search = 2;
418 }
419 if ($search[$key] != '') {
420 $sql .= natural_search("t.".$db->sanitize($key), $search[$key], (($key == 'status') ? 2 : $mode_search));
421 }
422 } else {
423 if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') {
424 $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key);
425 if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) {
426 if (preg_match('/_dtstart$/', $key)) {
427 $sql .= " AND t.".$db->sanitize($columnName)." >= '".$db->idate($search[$key])."'";
428 }
429 if (preg_match('/_dtend$/', $key)) {
430 $sql .= " AND t.".$db->sanitize($columnName)." <= '".$db->idate($search[$key])."'";
431 }
432 }
433 }
434 }
435}
436
437
438if ($search_all) {
439 $sql .= natural_search(array_keys($fieldstosearchall), $search_all);
440}
441
442// Search for tag/category ($searchCategoryMoList is an array of ID)
443if (!empty($searchCategoryMoList)) {
444 $searchCategoryMoSqlList = array();
445 $listofcategoryid = '';
446 foreach ($searchCategoryMoList as $searchCategoryMo) {
447 if (intval($searchCategoryMo) == -2) {
448 $searchCategoryMoSqlList[] = "NOT EXISTS (SELECT ck.fk_mo FROM ".MAIN_DB_PREFIX."categorie_mo as ck WHERE t.rowid = ck.fk_mo)";
449 } elseif (intval($searchCategoryMo) > 0) {
450 if ($searchCategoryMoOperator == 0) {
451 $searchCategoryMoSqlList[] = " EXISTS (SELECT ck.fk_mo FROM ".MAIN_DB_PREFIX."categorie_mo as ck WHERE t.rowid = ck.fk_mo AND ck.fk_categorie = ".((int) $searchCategoryMo).")";
452 } else {
453 $listofcategoryid .= ($listofcategoryid ? ', ' : '') . ((int) $searchCategoryMo);
454 }
455 }
456 }
457 if ($listofcategoryid) {
458 $searchCategoryMoSqlList[] = " EXISTS (SELECT ck.fk_mo FROM ".MAIN_DB_PREFIX."categorie_mo as ck WHERE t.rowid = ck.fk_mo AND ck.fk_categorie IN (".$db->sanitize($listofcategoryid)."))";
459 }
460 if ($searchCategoryMoOperator == 1) {
461 if (!empty($searchCategoryMoSqlList)) {
462 $sql .= " AND (".implode(' OR ', $searchCategoryMoSqlList).")";
463 }
464 } else {
465 if (!empty($searchCategoryMoSqlList)) {
466 $sql .= " AND (".implode(' AND ', $searchCategoryMoSqlList).")";
467 }
468 }
469}
470
471
472
473//$sql.= dolSqlDateFilter("t.field", $search_xxxday, $search_xxxmonth, $search_xxxyear);
474// Add where from extra fields
475include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
476// Add where from hooks
477$parameters = array();
478$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
479$sql .= $hookmanager->resPrint;
480/* If a group by is required
481$sql.= " GROUP BY ";
482foreach($object->fields as $key => $val) {
483 $sql .= "t.".$db->sanitize($key).", ";
484}
485// Add fields from extrafields
486if (!empty($extrafields->attributes[$object->table_element]['label'])) {
487 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
488 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : '');
489 }
490}
491// Add groupby from hooks
492$parameters=array();
493$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
494$sql.=$hookmanager->resPrint;
495$sql=preg_replace('/,\s*$/','', $sql);
496*/
497
498// Count total nb of records
499$nbtotalofrecords = '';
500if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
501 /* The fast and low memory method to get and count full list converts the sql into a sql count */
502 $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
503 $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
504 $resql = $db->query($sqlforcount);
505 if ($resql) {
506 $objforcount = $db->fetch_object($resql);
507 $nbtotalofrecords = $objforcount->nbtotalofrecords;
508 } else {
510 }
511
512 if (($page * $limit) > (int) $nbtotalofrecords) { // if total resultset is smaller than the paging size (filtering), goto and load page 0
513 $page = 0;
514 $offset = 0;
515 }
516 $db->free($resql);
517}
518
519// Complete request and execute it with limit
520$sql .= $db->order($sortfield, $sortorder);
521if ($limit) {
522 $sql .= $db->plimit($limit + 1, $offset);
523}
524$resql = $db->query($sql);
525if (!$resql) {
527 exit;
528}
529
530$num = $db->num_rows($resql);
531
532// Direct jump if only one record found
533if ($num == 1 && getDolGlobalInt('MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE') && $search_all && !$page) {
534 $obj = $db->fetch_object($resql);
535 $id = $obj->rowid;
536 header("Location: ".dol_buildpath('/mrp/mo_card.php', 1).'?id='.((int) $id));
537 exit;
538}
539
540
541// Output page
542// --------------------------------------------------------------------
543
544llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'bodyforlist mod-mrp page-list');
545
546
547$arrayofselected = is_array($toselect) ? $toselect : array();
548
549$param = '';
550if (!empty($mode)) {
551 $param .= '&mode='.urlencode($mode);
552}
553if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
554 $param .= '&contextpage='.urlencode($contextpage);
555}
556if ($limit > 0 && $limit != $conf->liste_limit) {
557 $param .= '&limit='.((int) $limit);
558}
559if ($optioncss != '') {
560 $param .= '&optioncss='.urlencode($optioncss);
561}
562if ($groupby != '') {
563 $param .= '&groupby='.urlencode($groupby);
564}
565foreach ($search as $key => $val) {
566 if (is_array($search[$key])) {
567 foreach ($search[$key] as $skey) {
568 if ($skey != '') {
569 $param .= '&search_'.$key.'[]='.urlencode($skey);
570 }
571 }
572 } elseif (preg_match('/(_dtstart|_dtend)$/', $key) && !empty($val)) {
573 $param .= '&search_'.$key.'month='.GETPOSTINT('search_'.$key.'month');
574 $param .= '&search_'.$key.'day='.GETPOSTINT('search_'.$key.'day');
575 $param .= '&search_'.$key.'year='.GETPOSTINT('search_'.$key.'year');
576 } elseif ($search[$key] != '') {
577 $param .= '&search_'.$key.'='.urlencode((string) $search[$key]);
578 }
579}
580if ($searchCategoryMoOperator == 1) {
581 $param .= '&search_category_mo_operator='.urlencode((string) ($searchCategoryMoOperator));
582}
583foreach ($searchCategoryMoList as $searchCategoryMo) {
584 $param .= '&search_category_mo_list[]='.urlencode($searchCategoryMo);
585}
586// Add $param from extra fields
587include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
588// Add $param from hooks
589$parameters = array('param' => &$param);
590$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
591$param .= $hookmanager->resPrint;
592
593// List of mass actions available
594$arrayofmassactions = array(
595 'validate'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"),
596 'precancel'=>img_picto('', 'close_title', 'class="pictofixedwidth"').$langs->trans("Cancel"),
597 'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"),
598 'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
599 'predatestart'=>img_picto('', 'object_calendar', 'class="pictofixedwidth"').$langs->trans("MoChangeDateStart"),
600 'predateend'=>img_picto('', 'object_calendar', 'class="pictofixedwidth"').$langs->trans("MoChangeDateEnd"),
601 //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
602);
603if (isModEnabled('category') && $permissiontoadd) {
604 $arrayofmassactions['preaffecttag'] = img_picto('', 'category', 'class="pictofixedwidth"').$langs->trans("AffectTag");
605}
606if (!empty($permissiontodelete)) {
607 $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
608}
609if (GETPOSTINT('nomassaction') || in_array($massaction, array('presend', 'predelete', 'preaffecttag'))) {
610 $arrayofmassactions = array();
611}
612$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
613
614print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
615if ($optioncss != '') {
616 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
617}
618print '<input type="hidden" name="token" value="'.newToken().'">';
619print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
620print '<input type="hidden" name="action" value="list">';
621print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
622print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
623print '<input type="hidden" name="page" value="'.$page.'">';
624print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
625print '<input type="hidden" name="page_y" value="">';
626print '<input type="hidden" name="mode" value="'.$mode.'">';
627
628$newcardbutton = '';
629$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'));
630$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'));
631$newcardbutton .= dolGetButtonTitleSeparator();
632$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/mrp/mo_card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd);
633
634print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1);
635
636// Add code for pre mass action (confirmation or email presend form)
637$topicmail = "SendMoRef";
638$modelmail = "mo";
639$objecttmp = new Mo($db);
640$trackid = 'mo'.$object->id;
641include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
642
643if ($massaction == 'precancel') {
644 $formquestion = array(
645 array(
646 'label' => $langs->trans('MoCancelConsumedAndProducedLines'),
647 'name' => 'alsoCancelConsumedAndProducedLines',
648 'type' => 'checkbox',
649 'value' => 0
650 ),
651 );
652
653 print $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'],
654 $langs->trans('CancelMo'),
655 $langs->trans('ConfirmCancelMo'),
656 'confirm_cancel', $formquestion,
657 1, 0, 200, 500, 1);
658}
659
660if ($massaction == 'predatestart') {
661 $formquestion = array(
662 array(
663 'type' => 'datetime',
664 'tdclass' => 'fieldrequired',
665 'name' => 'change_date',
666 'label' => $langs->trans('ModifyDateStart'),
667 'value' => -1),
668 );
669 print $form->formconfirm($_SERVER['PHP_SELF'],
670 $langs->trans('ConfirmMassChangeDateStart'),
671 $langs->trans('ConfirmMassChangeDateStartQuestion',
672 count($toselect)), 'changedatestart_confirm', $formquestion,
673 '', 0, 200, 500, 1);
674}
675
676if ($massaction == 'predateend') {
677 $formquestion = array(
678 array(
679 'type' => 'datetime',
680 'tdclass' => 'fieldrequired',
681 'name' => 'change_date',
682 'label' => $langs->trans('ModifyDateEnd'),
683 'value' => -1),
684 );
685 print $form->formconfirm($_SERVER['PHP_SELF'],
686 $langs->trans('ConfirmMassChangeDateEnd'),
687 $langs->trans('ConfirmMassChangeDateEndQuestion',
688 count($toselect)), 'changedateend_confirm', $formquestion,
689 '', 0, 200, 500, 1);
690}
691
692if ($search_all) {
693 foreach ($fieldstosearchall as $key => $val) {
694 $fieldstosearchall[$key] = $langs->trans($val);
695 }
696 print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).implode(', ', $fieldstosearchall).'</div>';
697}
698
699$moreforfilter = '';
700/*$moreforfilter.='<div class="divsearchfield">';
701$moreforfilter.= $langs->trans('MyFilter') . ': <input type="text" name="search_myfield" value="'.dol_escape_htmltag($search_myfield).'">';
702$moreforfilter.= '</div>';*/
703if (isModEnabled('category') && $user->hasRight('categorie', 'read')) {
704 $formcategory = new FormCategory($db);
705 $moreforfilter .= $formcategory->getFilterBox(Categorie::TYPE_MO, $searchCategoryMoList, 'minwidth300', $searchCategoryMoOperator ? $searchCategoryMoOperator : 0);
706}
707
708$parameters = array();
709$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
710if (empty($reshook)) {
711 $moreforfilter .= $hookmanager->resPrint;
712} else {
713 $moreforfilter = $hookmanager->resPrint;
714}
715
716if (!empty($moreforfilter)) {
717 print '<div class="liste_titre liste_titre_bydiv centpercent">';
718 print $moreforfilter;
719 print '</div>';
720}
721
722$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
723$htmlofselectarray = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, $conf->main_checkbox_left_column); // This also change content of $arrayfields with user setup
724$selectedfields = ($mode != 'kanban' ? $htmlofselectarray : '');
725$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
726
727print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
728print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
729
730
731// Fields title search
732// --------------------------------------------------------------------
733print '<tr class="liste_titre_filter">';
734// Action column
735if ($conf->main_checkbox_left_column) {
736 print '<td class="liste_titre center maxwidthsearch">';
737 $searchpicto = $form->showFilterButtons('left');
738 print $searchpicto;
739 print '</td>';
740}
741foreach ($object->fields as $key => $val) {
742 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
743 if ($key == 'status') {
744 $cssforfield .= ($cssforfield ? ' ' : '').'center';
745 } elseif ($key == 'fk_parent_line') {
746 $cssforfield .= ($cssforfield ? ' ' : '').'center';
747 } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
748 $cssforfield .= ($cssforfield ? ' ' : '').'center';
749 } elseif (in_array($val['type'], array('timestamp'))) {
750 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
751 } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) {
752 $cssforfield .= ($cssforfield ? ' ' : '').'right';
753 }
754 if (!empty($arrayfields['t.'.$key]['checked'])) {
755 print '<td class="liste_titre'.($cssforfield ? ' '.$cssforfield : '').'">';
756 if ($key == 'fk_parent_line') {
757 print '<input type="text" class="flat maxwidth75" name="search_fk_parent_line">';
758 print '</td>';
759 continue;
760 }
761 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
762 if ($key == 'status') {
763 $val['arrayofkeyval'][-2] = $langs->trans("StatusMrpValidated").'+'.$langs->trans("StatusMrpProgress");
764 print $form->multiselectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) && $search[$key] !== '' && $search[$key] != -1 ? (array) $search[$key] : array()), 0, 0, 'maxwidth100', 0, 0, '', '', '');
765 } else {
766 print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1);
767 }
768 } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) {
769 print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', $cssforfield.' maxwidth125', 1);
770 } elseif (!preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
771 print '<input type="text" class="flat maxwidth'.($val['type'] == 'integer' ? '50' : '75').'" name="search_'.$key.'" value="'.dol_escape_htmltag(isset($search[$key]) ? $search[$key] : '').'">';
772 } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
773 print '<div class="nowrap">';
774 print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
775 print '</div>';
776 print '<div class="nowrap">';
777 print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
778 print '</div>';
779 }
780 print '</td>';
781 }
782}
783// Extra fields
784include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
785
786// Fields from hook
787$parameters = array('arrayfields' => $arrayfields);
788$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
789print $hookmanager->resPrint;
790// Action column
791if (!$conf->main_checkbox_left_column) {
792 print '<td class="liste_titre center maxwidthsearch">';
793 $searchpicto = $form->showFilterButtons();
794 print $searchpicto;
795 print '</td>';
796}
797print '</tr>'."\n";
798
799$totalarray = array();
800$totalarray['nbfield'] = 0;
801
802
803// Fields title label
804// --------------------------------------------------------------------
805print '<tr class="liste_titre">';
806// Action column
807if ($conf->main_checkbox_left_column) {
808 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
809 $totalarray['nbfield']++;
810}
811foreach ($object->fields as $key => $val) {
812 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
813 if ($key == 'status') {
814 $cssforfield .= ($cssforfield ? ' ' : '').'center';
815 } elseif ($key == 'fk_parent_line') {
816 $cssforfield .= ($cssforfield ? ' ' : '').'center';
817 } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
818 $cssforfield .= ($cssforfield ? ' ' : '').'center';
819 } elseif (in_array($val['type'], array('timestamp'))) {
820 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
821 } 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'])) {
822 $cssforfield .= ($cssforfield ? ' ' : '').'right';
823 }
824 $cssforfield = preg_replace('/small\s*/', '', $cssforfield); // the 'small' css must not be used for the title label
825 if (!empty($arrayfields['t.'.$key]['checked'])) {
826 if ($key == "fk_product") {
827 print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 'p.ref', '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''))."\n";
828 } else {
829 print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''))."\n";
830 }
831 $totalarray['nbfield']++;
832 }
833}
834// Extra fields
835include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
836// Hook fields
837$parameters = array('arrayfields' => $arrayfields, 'param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder, 'totalarray' => &$totalarray);
838$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
839print $hookmanager->resPrint;
840// Action column
841if (!$conf->main_checkbox_left_column) {
842 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
843 $totalarray['nbfield']++;
844}
845print '</tr>'."\n";
846
847
848// Detect if we need a fetch on each output line
849$needToFetchEachLine = 0;
850if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) {
851 foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) {
852 if (!is_null($val) && preg_match('/\$object/', $val)) {
853 $needToFetchEachLine++; // There is at least one compute field that use $object
854 }
855 }
856}
857
858
859$bom = new BOM($db);
860$product = new Product($db);
861
862// Loop on record
863// --------------------------------------------------------------------
864$i = 0;
865$savnbfield = $totalarray['nbfield'];
866$totalarray = array();
867$totalarray['nbfield'] = 0;
868$imaxinloop = ($limit ? min($num, $limit) : $num);
869while ($i < $imaxinloop) {
870 $obj = $db->fetch_object($resql);
871 if (empty($obj)) {
872 break; // Should not happen
873 }
874
875 // Store properties in $object
876 $object->setVarsFromFetchObj($obj);
877
878
879 if ($mode == 'kanban' || $mode == 'kanbangroupby') {
880 if ($i == 0) {
881 print '<tr class="trkanban"><td colspan="'.$savnbfield.'">';
882 print '<div class="box-flex-container kanban">';
883 }
884 //$object->type_id = $obj->type_id;
885
886 // TODO Use a cache on BOM
887 if ($obj->fk_bom > 0) {
888 $bom->fetch($obj->fk_bom);
889 }
890 if ($obj->fk_product > 0) {
891 $product->fetch($obj->fk_product);
892 }
893
894 // Output Kanban
895 $selected = -1;
896 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
897 $selected = 0;
898 if (in_array($object->id, $arrayofselected)) {
899 $selected = 1;
900 }
901 }
902 print $object->getKanbanView('', array('bom' => ($obj->fk_bom > 0 ? $bom : null), 'product' => ($obj->fk_product > 0 ? $product : null), 'selected' => $selected));
903 if ($i == ($imaxinloop - 1)) {
904 print '</div>';
905 print '</td></tr>';
906 }
907 } else {
908 // Show line of result
909 $j = 0;
910 print '<tr data-rowid="'.$object->id.'" class="oddeven row-with-select">';
911
912 // Action column
913 if ($conf->main_checkbox_left_column) {
914 print '<td class="nowrap center">';
915 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
916 $selected = 0;
917 if (in_array($object->id, $arrayofselected)) {
918 $selected = 1;
919 }
920 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
921 }
922 print '</td>';
923 if (!$i) {
924 $totalarray['nbfield']++;
925 }
926 }
927 // Fields
928 foreach ($object->fields as $key => $val) {
929 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
930 if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
931 $cssforfield .= ($cssforfield ? ' ' : '').'center';
932 } elseif ($key == 'status') {
933 $cssforfield .= ($cssforfield ? ' ' : '').'center';
934 } elseif ($key == 'fk_parent_line') {
935 $cssforfield .= ($cssforfield ? ' ' : '').'center';
936 }
937
938 if (in_array($val['type'], array('timestamp'))) {
939 $cssforfield .= ($cssforfield ? ' ' : '').'nowraponall';
940 } elseif ($key == 'ref') {
941 $cssforfield .= ($cssforfield ? ' ' : '').'nowraponall';
942 }
943
944 if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('id', 'rowid', 'ref', 'status')) && empty($val['arrayofkeyval'])) {
945 $cssforfield .= ($cssforfield ? ' ' : '').'right';
946 }
947
948 if (!empty($arrayfields['t.'.$key]['checked'])) {
949 print '<td'.($cssforfield ? ' class="'.$cssforfield.((preg_match('/tdoverflow/', $cssforfield) && !in_array($val['type'], array('ip', 'url')) && !is_numeric($object->$key)) ? ' classfortooltip' : '').'"' : '');
950 if (preg_match('/tdoverflow/', $cssforfield) && !in_array($val['type'], array('ip', 'url')) && !is_numeric($object->$key)) {
951 print ' title="'.dolPrintHTMLForAttribute((string) $object->$key).'"';
952 }
953 print '>';
954 if ($key == 'status') {
955 print $object->getLibStatut(5);
956 } elseif ($key == 'fk_parent_line') {
957 $moparent = $object->getMoParent();
958 if (is_object($moparent)) {
959 print $moparent->getNomUrl(1);
960 }
961 } elseif ($key == 'rowid') {
962 print $object->showOutputField($val, $key, (string) $object->id, '');
963 } else {
964 if ($val['type'] == 'html') {
965 print '<div class="small lineheightsmall twolinesmax-normallineheight">';
966 }
967 print $object->showOutputField($val, $key, (string) $object->$key, '');
968 if ($val['type'] == 'html') {
969 print '</div>';
970 }
971
972 if ($key == 'date_end_planned' && $object->hasDelay()) {
973 print img_warning($langs->trans('Alert').' - '.$langs->trans('Late'));
974 }
975 }
976 print '</td>';
977 if (!$i) {
978 $totalarray['nbfield']++;
979 }
980 if (!empty($val['isameasure']) && $val['isameasure'] == 1) {
981 if (!$i) {
982 $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key;
983 }
984 if (!isset($totalarray['val'])) {
985 $totalarray['val'] = array();
986 }
987 if (!isset($totalarray['val']['t.'.$key])) {
988 $totalarray['val']['t.'.$key] = 0;
989 }
990 $totalarray['val']['t.'.$key] += $object->$key;
991 }
992 }
993 }
994 // Extra fields
995 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
996 // Fields from hook
997 $parameters = array('arrayfields' => $arrayfields, 'object' => $object, 'obj' => $obj, 'i' => $i, 'totalarray' => &$totalarray);
998 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
999 print $hookmanager->resPrint;
1000
1001 // Action column
1002 if (!$conf->main_checkbox_left_column) {
1003 print '<td class="nowrap center">';
1004 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
1005 $selected = 0;
1006 if (in_array($object->id, $arrayofselected)) {
1007 $selected = 1;
1008 }
1009 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
1010 }
1011 print '</td>';
1012 if (!$i) {
1013 $totalarray['nbfield']++;
1014 }
1015 }
1016
1017 print '</tr>'."\n";
1018 }
1019 $i++;
1020}
1021
1022// Show total line
1023include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
1024
1025
1026// If no record found
1027if ($num == 0) {
1028 $colspan = 1;
1029 foreach ($arrayfields as $key => $val) {
1030 if (!empty($val['checked'])) {
1031 $colspan++;
1032 }
1033 }
1034 print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
1035}
1036
1037
1038$db->free($resql);
1039
1040$parameters = array('arrayfields' => $arrayfields, 'sql' => $sql);
1041$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1042print $hookmanager->resPrint;
1043
1044print '</table>'."\n";
1045print '</div>'."\n";
1046
1047print '</form>'."\n";
1048
1049if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
1050 $hidegeneratedfilelistifempty = 1;
1051 if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
1052 $hidegeneratedfilelistifempty = 0;
1053 }
1054
1055 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
1056 $formfile = new FormFile($db);
1057
1058 // Show list of available documents
1059 $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
1060 $urlsource .= str_replace('&amp;', '&', $param);
1061
1062 $filedir = $diroutputmassaction;
1063 $genallowed = $permissiontoread;
1064 $delallowed = $permissiontoadd;
1065
1066 print $formfile->showdocuments('massfilesarea_mrp', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
1067}
1068
1069// End of page
1070llxFooter();
1071$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
$totalarray
Definition list.php:501
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
Class for BOM.
Definition bom.class.php:42
Class to manage forms for categories.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class for Mo.
Definition mo.class.php:35
Class to manage products or services.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
dol_eval($s, $returnvalue=1, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
natural_search($fields, $value, $mode=0, $nofirstand=0, $sqltoadd='')
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by the value of a given key, which produces ascending (default) or descending out...
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
getWarningDelay($module, $parmlevel1, $parmlevel2='')
Return a warning delay You can use it like this: if (getWarningDelay('module', 'paramlevel1')) It rep...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $selectlimitsuffix=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
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.
getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $disablesortlink=0, $tooltip='', $forcenowrapcolumntitle=0)
Get title line of an array.
dolGetButtonTitleSeparator($moreClass="")
Add space between dolGetButtonTitle.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
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...
Definition html.lib.php:172
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
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.