forked from Wavyzz/dolibarr
# Qual: Fix PhanPluginDuplicateIfStatements & remove exceptions Fix occurences of PhanPluginDuplicateIfStatements which are if statements where the consecutive branches execute the same code, making it useles to test the condition
859 lines
34 KiB
PHP
859 lines
34 KiB
PHP
<?php
|
|
/* Copyright (C) 2007-2017 Laurent Destailleur <eldy@users.sourceforge.net>
|
|
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/**
|
|
* \file htdocs/bom/bom_list.php
|
|
* \ingroup bom
|
|
* \brief List page for BillOfMaterials
|
|
*/
|
|
|
|
// Load Dolibarr environment
|
|
require '../main.inc.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
|
|
|
|
// Load translation files required by the page
|
|
$langs->loadLangs(array('mrp', 'other'));
|
|
|
|
// Get Parameters
|
|
$id = GETPOSTINT('id');
|
|
$action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ...
|
|
$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
|
|
$show_files = GETPOSTINT('show_files'); // Show files area generated by bulk actions ?
|
|
$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation
|
|
$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button
|
|
$toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list
|
|
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'bomlist'; // To manage different context of search
|
|
$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
|
|
$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
|
|
$mode = GETPOST('mode', 'aZ'); // mode view (kanban or common)
|
|
|
|
|
|
// Load variable for pagination
|
|
$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
|
|
$sortfield = GETPOST('sortfield', 'aZ09comma');
|
|
$sortorder = GETPOST('sortorder', 'aZ09comma');
|
|
$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT('page');
|
|
if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
|
|
// If $page is not defined, or '' or -1 or if we click on clear filters
|
|
$page = 0;
|
|
}
|
|
$offset = $limit * $page;
|
|
$pageprev = $page - 1;
|
|
$pagenext = $page + 1;
|
|
//if (! $sortfield) $sortfield="p.date_fin";
|
|
//if (! $sortorder) $sortorder="DESC";
|
|
|
|
// Initialize technical objects
|
|
$object = new BOM($db);
|
|
$extrafields = new ExtraFields($db);
|
|
$diroutputmassaction = $conf->bom->dir_output.'/temp/massgeneration/'.$user->id;
|
|
$hookmanager->initHooks(array('bomlist')); // Note that conf->hooks_modules contains array
|
|
|
|
// Fetch optionals attributes and labels
|
|
$extrafields->fetch_name_optionals_label($object->table_element);
|
|
|
|
$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
|
|
|
|
// Default sort order (if not yet defined by previous GETPOST)
|
|
if (!$sortfield) {
|
|
reset($object->fields); // Reset is required to avoid key() to return null.
|
|
$sortfield = "t.".key($object->fields); // Set here default search field. By default 1st field in definition.
|
|
}
|
|
if (!$sortorder) {
|
|
$sortorder = "ASC";
|
|
}
|
|
|
|
// Initialize array of search criteria
|
|
$search_all = trim(GETPOST('search_all', 'alphanohtml'));
|
|
$search = array();
|
|
foreach ($object->fields as $key => $val) {
|
|
if (GETPOST('search_'.$key, 'alpha') !== '') {
|
|
$search[$key] = GETPOST('search_'.$key, 'alpha');
|
|
}
|
|
if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
|
|
$search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOSTINT('search_'.$key.'_dtstartmonth'), GETPOSTINT('search_'.$key.'_dtstartday'), GETPOSTINT('search_'.$key.'_dtstartyear'));
|
|
$search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOSTINT('search_'.$key.'_dtendmonth'), GETPOSTINT('search_'.$key.'_dtendday'), GETPOSTINT('search_'.$key.'_dtendyear'));
|
|
}
|
|
}
|
|
|
|
$fieldstosearchall = array();
|
|
// List of fields to search into when doing a "search in all"
|
|
foreach ($object->fields as $key => $val) {
|
|
if (!empty($val['searchall'])) {
|
|
$fieldstosearchall['t.'.$key] = $val['label'];
|
|
}
|
|
}
|
|
|
|
// Definition of array of fields for columns
|
|
$arrayfields = array();
|
|
foreach ($object->fields as $key => $val) {
|
|
// If $val['visible']==0, then we never show the field
|
|
if (!empty($val['visible'])) {
|
|
$visible = (int) dol_eval($val['visible'], 1);
|
|
$arrayfields['t.'.$key] = array(
|
|
'label' => $val['label'],
|
|
'checked' => (($visible < 0) ? 0 : 1),
|
|
'enabled' => (abs($visible) != 3 && (int) dol_eval($val['enabled'], 1)),
|
|
'position' => $val['position'],
|
|
'help' => isset($val['help']) ? $val['help'] : ''
|
|
);
|
|
}
|
|
}
|
|
// Extra fields
|
|
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
|
|
|
|
$object->fields = dol_sort_array($object->fields, 'position');
|
|
$arrayfields = dol_sort_array($arrayfields, 'position');
|
|
|
|
$permissiontoread = $user->hasRight('bom', 'read');
|
|
$permissiontoadd = $user->hasRight('bom', 'write');
|
|
$permissiontodelete = $user->hasRight('bom', 'delete');
|
|
|
|
// Security check
|
|
if ($user->socid > 0) {
|
|
// Protection if external user
|
|
accessforbidden();
|
|
}
|
|
$result = restrictedArea($user, 'bom');
|
|
|
|
|
|
/*
|
|
* Actions
|
|
*/
|
|
|
|
if (GETPOST('cancel', 'alpha')) {
|
|
$action = 'list';
|
|
$massaction = '';
|
|
}
|
|
if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
|
|
$massaction = '';
|
|
}
|
|
|
|
$parameters = array();
|
|
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
|
|
if ($reshook < 0) {
|
|
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
|
|
}
|
|
|
|
if (empty($reshook)) {
|
|
// Selection of new fields
|
|
include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
|
|
|
|
// Purge search criteria
|
|
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
|
|
foreach ($object->fields as $key => $val) {
|
|
$search[$key] = '';
|
|
if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
|
|
$search[$key.'_dtstart'] = '';
|
|
$search[$key.'_dtend'] = '';
|
|
}
|
|
}
|
|
$toselect = array();
|
|
$search_array_options = array();
|
|
}
|
|
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
|
|
|| GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
|
|
$massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
|
|
}
|
|
|
|
// Mass actions
|
|
$objectclass = 'BOM';
|
|
$objectlabel = 'BillOfMaterials';
|
|
$permissiontoread = $user->hasRight('bom', 'read');
|
|
$permissiontodelete = $user->hasRight('bom', 'delete');
|
|
$uploaddir = $conf->bom->dir_output;
|
|
include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
|
|
|
|
|
|
// Validate records
|
|
if (!$error && $massaction == 'disable' && $permissiontoadd) {
|
|
$objecttmp = new $objectclass($db);
|
|
|
|
if (!$error) {
|
|
$db->begin();
|
|
|
|
$nbok = 0;
|
|
foreach ($toselect as $toselectid) {
|
|
$result = $objecttmp->fetch($toselectid);
|
|
if ($result > 0) {
|
|
if ($objecttmp->status != $objecttmp::STATUS_VALIDATED) {
|
|
$langs->load("errors");
|
|
setEventMessages($langs->trans("ErrorObjectMustHaveStatusActiveToBeDisabled", $objecttmp->ref), null, 'errors');
|
|
$error++;
|
|
break;
|
|
}
|
|
|
|
// Can be 'cancel()' or 'close()'
|
|
$result = $objecttmp->cancel($user);
|
|
if ($result < 0) {
|
|
setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
|
|
$error++;
|
|
break;
|
|
} else {
|
|
$nbok++;
|
|
}
|
|
} else {
|
|
setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
|
|
$error++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
setEventMessages($langs->trans("RecordsModified", $nbok), null, 'mesgs');
|
|
$db->commit();
|
|
} else {
|
|
$db->rollback();
|
|
}
|
|
//var_dump($listofobjectthirdparties);exit;
|
|
}
|
|
}
|
|
|
|
// Validate records
|
|
if (!$error && $massaction == 'enable' && $permissiontoadd) {
|
|
$objecttmp = new $objectclass($db);
|
|
|
|
if (!$error) {
|
|
$db->begin();
|
|
|
|
$nbok = 0;
|
|
foreach ($toselect as $toselectid) {
|
|
$result = $objecttmp->fetch($toselectid);
|
|
if ($result > 0) {
|
|
if ($objecttmp->status != $objecttmp::STATUS_DRAFT && $objecttmp->status != $objecttmp::STATUS_CANCELED) {
|
|
$langs->load("errors");
|
|
setEventMessages($langs->trans("ErrorObjectMustHaveStatusDraftOrDisabledToBeActivated", $objecttmp->ref), null, 'errors');
|
|
$error++;
|
|
break;
|
|
}
|
|
|
|
// Can be 'cancel()' or 'close()'
|
|
$result = $objecttmp->validate($user);
|
|
if ($result < 0) {
|
|
setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
|
|
$error++;
|
|
break;
|
|
} else {
|
|
$nbok++;
|
|
}
|
|
} else {
|
|
setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
|
|
$error++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
setEventMessages($langs->trans("RecordsModified", $nbok), null, 'mesgs');
|
|
$db->commit();
|
|
} else {
|
|
$db->rollback();
|
|
}
|
|
//var_dump($listofobjectthirdparties);exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* View
|
|
*/
|
|
|
|
$form = new Form($db);
|
|
|
|
$now = dol_now();
|
|
|
|
$title = $langs->trans('ListOfBOMs');
|
|
$help_url = 'EN:Module_BOM';
|
|
$morejs = array();
|
|
$morecss = array();
|
|
|
|
|
|
// Build and execute select
|
|
// --------------------------------------------------------------------
|
|
$sql = 'SELECT ';
|
|
$sql .= $object->getFieldList('t');
|
|
// Add fields from extrafields
|
|
if (!empty($extrafields->attributes[$object->table_element]['label'])) {
|
|
foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
|
|
$sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
|
|
}
|
|
}
|
|
// Add fields from hooks
|
|
$parameters = array();
|
|
$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
$sql .= $hookmanager->resPrint;
|
|
$sql = preg_replace('/,\s*$/', '', $sql);
|
|
|
|
$sqlfields = $sql; // $sql fields to remove for count total
|
|
|
|
$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
|
|
if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
|
|
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)";
|
|
}
|
|
// Add table from hooks
|
|
$parameters = array();
|
|
$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
$sql .= $hookmanager->resPrint;
|
|
if ($object->ismultientitymanaged == 1) {
|
|
$sql .= " WHERE t.entity IN (".getEntity($object->element, (GETPOSTINT('search_current_entity') ? 0 : 1)).")";
|
|
} else {
|
|
$sql .= " WHERE 1 = 1";
|
|
}
|
|
foreach ($search as $key => $val) {
|
|
if (array_key_exists($key, $object->fields)) {
|
|
if ($key == 'status' && $search[$key] == -1) {
|
|
continue;
|
|
}
|
|
$mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0);
|
|
if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) {
|
|
if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) {
|
|
$search[$key] = '';
|
|
}
|
|
$mode_search = 2;
|
|
}
|
|
if ($search[$key] != '') {
|
|
$sql .= natural_search("t.".$db->sanitize($key), $search[$key], (($key == 'status') ? 2 : $mode_search));
|
|
}
|
|
} else {
|
|
if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') {
|
|
$columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key);
|
|
if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) {
|
|
if (preg_match('/_dtstart$/', $key)) {
|
|
$sql .= " AND t.".$db->sanitize($columnName)." >= '".$db->idate($search[$key])."'";
|
|
}
|
|
if (preg_match('/_dtend$/', $key)) {
|
|
$sql .= " AND t.".$db->sanitize($columnName)." <= '".$db->idate($search[$key])."'";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($search_all) {
|
|
$sql .= natural_search(array_keys($fieldstosearchall), $search_all);
|
|
}
|
|
//$sql.= dolSqlDateFilter("t.field", $search_xxxday, $search_xxxmonth, $search_xxxyear);
|
|
// Add where from extra fields
|
|
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
|
|
// Add where from hooks
|
|
$parameters = array();
|
|
$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
$sql .= $hookmanager->resPrint;
|
|
|
|
/* If a group by is required
|
|
$sql.= " GROUP BY ";
|
|
foreach($object->fields as $key => $val) {
|
|
$sql .= "t.".$db->escape($key).", ";
|
|
}
|
|
// Add fields from extrafields
|
|
if (!empty($extrafields->attributes[$object->table_element]['label'])) {
|
|
foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
|
|
$sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : '');
|
|
}
|
|
}
|
|
// Add groupby from hooks
|
|
$parameters=array();
|
|
$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
$sql.=$hookmanager->resPrint;
|
|
$sql=preg_replace('/,\s*$/','', $sql);
|
|
*/
|
|
|
|
// Count total nb of records
|
|
$nbtotalofrecords = '';
|
|
if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
|
|
/* The fast and low memory method to get and count full list converts the sql into a sql count */
|
|
$sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
|
|
$sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
|
|
$resql = $db->query($sqlforcount);
|
|
if ($resql) {
|
|
$objforcount = $db->fetch_object($resql);
|
|
$nbtotalofrecords = $objforcount->nbtotalofrecords;
|
|
} else {
|
|
dol_print_error($db);
|
|
}
|
|
|
|
if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller than the paging size (filtering), goto and load page 0
|
|
$page = 0;
|
|
$offset = 0;
|
|
}
|
|
$db->free($resql);
|
|
}
|
|
|
|
// Complete request and execute it with limit
|
|
$sql .= $db->order($sortfield, $sortorder);
|
|
if ($limit) {
|
|
$sql .= $db->plimit($limit + 1, $offset);
|
|
}
|
|
|
|
$resql = $db->query($sql);
|
|
if (!$resql) {
|
|
dol_print_error($db);
|
|
exit;
|
|
}
|
|
|
|
$num = $db->num_rows($resql);
|
|
|
|
// Direct jump if only one record found
|
|
if ($num == 1 && getDolGlobalInt('MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE') && $search_all && !$page) {
|
|
$obj = $db->fetch_object($resql);
|
|
$id = $obj->rowid;
|
|
header("Location: ".DOL_URL_ROOT.'/bom/bom_card.php?id='.((int) $id));
|
|
exit;
|
|
}
|
|
|
|
|
|
// Output page
|
|
// --------------------------------------------------------------------
|
|
|
|
llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'mod-bom page-list bodyforlist');
|
|
|
|
$arrayofselected = is_array($toselect) ? $toselect : array();
|
|
|
|
$param = '';
|
|
if (!empty($mode)) {
|
|
$param .= '&mode='.urlencode($mode);
|
|
}
|
|
if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
|
|
$param .= '&contextpage='.urlencode($contextpage);
|
|
}
|
|
if ($limit > 0 && $limit != $conf->liste_limit) {
|
|
$param .= '&limit='.((int) $limit);
|
|
}
|
|
if ($optioncss != '') {
|
|
$param .= '&optioncss='.urlencode($optioncss);
|
|
}
|
|
foreach ($search as $key => $val) {
|
|
if (is_array($search[$key])) {
|
|
foreach ($search[$key] as $skey) {
|
|
if ($skey != '') {
|
|
$param .= '&search_'.$key.'[]='.urlencode($skey);
|
|
}
|
|
}
|
|
} elseif (preg_match('/(_dtstart|_dtend)$/', $key) && !empty($val)) {
|
|
$param .= '&search_'.$key.'month='.(GETPOSTINT('search_'.$key.'month'));
|
|
$param .= '&search_'.$key.'day='.(GETPOSTINT('search_'.$key.'day'));
|
|
$param .= '&search_'.$key.'year='.(GETPOSTINT('search_'.$key.'year'));
|
|
} elseif ($search[$key] != '') {
|
|
$param .= '&search_'.$key.'='.urlencode($search[$key]);
|
|
}
|
|
}
|
|
// Add $param from extra fields
|
|
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
|
|
// Add $param from hooks
|
|
$parameters = array();
|
|
$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
$param .= $hookmanager->resPrint;
|
|
|
|
// List of mass actions available
|
|
$arrayofmassactions = array(
|
|
//'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
|
|
'enable' => img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Enable"),
|
|
'disable' => img_picto('', 'close_title', 'class="pictofixedwidth"').$langs->trans("Disable"),
|
|
);
|
|
if (!empty($permissiontodelete)) {
|
|
$arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
|
|
}
|
|
if (GETPOSTINT('nomassaction') || in_array($massaction, array('presend', 'predelete'))) {
|
|
$arrayofmassactions = array();
|
|
}
|
|
$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
|
|
|
|
print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
|
|
if ($optioncss != '') {
|
|
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
|
|
}
|
|
print '<input type="hidden" name="token" value="'.newToken().'">';
|
|
print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
|
|
print '<input type="hidden" name="action" value="list">';
|
|
print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
|
|
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
|
|
print '<input type="hidden" name="page" value="'.$page.'">';
|
|
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
|
|
print '<input type="hidden" name="page_y" value="">';
|
|
print '<input type="hidden" name="mode" value="'.$mode.'">';
|
|
|
|
$newcardbutton = '';
|
|
$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'));
|
|
$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'));
|
|
$newcardbutton .= dolGetButtonTitleSeparator();
|
|
$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/bom/bom_card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $user->hasRight('bom', 'write'));
|
|
|
|
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1);
|
|
|
|
// Add code for pre mass action (confirmation or email presend form)
|
|
$topicmail = "SendBillOfMaterialsRef";
|
|
$modelmail = "bom";
|
|
$objecttmp = new BOM($db);
|
|
$trackid = 'bom'.$object->id;
|
|
include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
|
|
|
|
if ($search_all) {
|
|
$setupstring = '';
|
|
foreach ($fieldstosearchall as $key => $val) {
|
|
$fieldstosearchall[$key] = $langs->trans($val);
|
|
$setupstring .= $key."=".$val.";";
|
|
}
|
|
print '<!-- Search done like if BOM_QUICKSEARCH_ON_FIELDS = '.$setupstring.' -->'."\n";
|
|
print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).implode(', ', $fieldstosearchall).'</div>'."\n";
|
|
}
|
|
|
|
$moreforfilter = '';
|
|
/*$moreforfilter.='<div class="divsearchfield">';
|
|
$moreforfilter.= $langs->trans('MyFilter') . ': <input type="text" name="search_myfield" value="'.dol_escape_htmltag($search_myfield).'">';
|
|
$moreforfilter.= '</div>';*/
|
|
|
|
$parameters = array();
|
|
$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
if (empty($reshook)) {
|
|
$moreforfilter .= $hookmanager->resPrint;
|
|
} else {
|
|
$moreforfilter = $hookmanager->resPrint;
|
|
}
|
|
|
|
if (!empty($moreforfilter)) {
|
|
print '<div class="liste_titre liste_titre_bydiv centpercent">';
|
|
print $moreforfilter;
|
|
$parameters = array();
|
|
$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
print $hookmanager->resPrint;
|
|
print '</div>';
|
|
}
|
|
|
|
$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
|
|
$selectedfields = ($mode != 'kanban' ? $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) : ''); // This also change content of $arrayfields
|
|
$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
|
|
|
|
print '<div class="div-table-responsive">';
|
|
print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
|
|
|
|
|
|
// Fields title search
|
|
// --------------------------------------------------------------------
|
|
print '<tr class="liste_titre_filter">';
|
|
|
|
// Action column
|
|
if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
|
|
print '<td class="liste_titre center maxwidthsearch">';
|
|
$searchpicto = $form->showFilterButtons('left');
|
|
print $searchpicto;
|
|
print '</td>';
|
|
}
|
|
|
|
foreach ($object->fields as $key => $val) {
|
|
$searchkey = empty($search[$key]) ? '' : $search[$key];
|
|
$cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
|
|
if ($key == 'status') {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'center';
|
|
} elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'center';
|
|
} elseif (in_array($val['type'], array('timestamp'))) {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
|
|
} 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'])) {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'right';
|
|
}
|
|
if (!empty($arrayfields['t.'.$key]['checked'])) {
|
|
print '<td class="liste_titre'.($cssforfield ? ' '.$cssforfield : '').($key == 'status' ? ' parentonrightofpage' : '').'">';
|
|
if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
|
|
print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), 1, 0, 0, '', 1, 0, 0, '', 'maxwidth100'.($key == 'status' ? ' search_status width100 onrightofpage' : ''), 1);
|
|
} elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) {
|
|
print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', $cssforfield.' maxwidth250', 1);
|
|
} elseif (!preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
|
|
print '<input type="text" class="flat maxwidth75" name="search_'.$key.'" value="'.dol_escape_htmltag(isset($search[$key]) ? $search[$key] : '').'">';
|
|
} elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
|
|
print '<div class="nowrap">';
|
|
print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
|
|
print '</div>';
|
|
print '<div class="nowrap">';
|
|
print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
|
|
print '</div>';
|
|
} elseif ($key == 'lang') {
|
|
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
|
|
$formadmin = new FormAdmin($db);
|
|
print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth150 maxwidth200', 2);
|
|
} else {
|
|
print '<input type="text" class="flat maxwidth75" name="search_'.$key.'" value="'.dol_escape_htmltag(isset($search[$key]) ? $search[$key] : '').'">';
|
|
}
|
|
print '</td>';
|
|
}
|
|
}
|
|
// Extra fields
|
|
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
|
|
|
|
// Fields from hook
|
|
$parameters = array('arrayfields' => $arrayfields);
|
|
$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
print $hookmanager->resPrint;
|
|
// Action column
|
|
if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
|
|
print '<td class="liste_titre center maxwidthsearch">';
|
|
$searchpicto = $form->showFilterButtons();
|
|
print $searchpicto;
|
|
print '</td>';
|
|
}
|
|
print '</tr>'."\n";
|
|
|
|
$totalarray = array();
|
|
$totalarray['nbfield'] = 0;
|
|
|
|
// Fields title label
|
|
// --------------------------------------------------------------------
|
|
print '<tr class="liste_titre">';
|
|
// Action column
|
|
if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
|
|
print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
|
|
$totalarray['nbfield']++;
|
|
}
|
|
foreach ($object->fields as $key => $val) {
|
|
$cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
|
|
if ($key == 'status') {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'center';
|
|
} elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'center';
|
|
} elseif (in_array($val['type'], array('timestamp'))) {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
|
|
} 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'])) {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'right';
|
|
}
|
|
$cssforfield = preg_replace('/small\s*/', '', $cssforfield); // the 'small' css must not be used for the title label
|
|
if (!empty($arrayfields['t.'.$key]['checked'])) {
|
|
print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''), 0, (empty($val['helplist']) ? '' : $val['helplist']))."\n";
|
|
$totalarray['nbfield']++;
|
|
}
|
|
}
|
|
// Extra fields
|
|
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
|
|
// Hook fields
|
|
$parameters = array('arrayfields' => $arrayfields, 'param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder, 'totalarray' => &$totalarray);
|
|
$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
print $hookmanager->resPrint;
|
|
// Action column
|
|
if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
|
|
print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
|
|
$totalarray['nbfield']++;
|
|
}
|
|
print '</tr>'."\n";
|
|
|
|
|
|
// Detect if we need a fetch on each output line
|
|
$needToFetchEachLine = 0;
|
|
if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) {
|
|
foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) {
|
|
if (!is_null($val) && preg_match('/\$object/', $val)) {
|
|
$needToFetchEachLine++; // There is at least one compute field that use $object
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Loop on record
|
|
// --------------------------------------------------------------------
|
|
$i = 0;
|
|
$savnbfield = $totalarray['nbfield'];
|
|
$totalarray = array();
|
|
$totalarray['nbfield'] = 0;
|
|
$imaxinloop = ($limit ? min($num, $limit) : $num);
|
|
while ($i < $imaxinloop) {
|
|
$obj = $db->fetch_object($resql);
|
|
if (empty($obj)) {
|
|
break; // Should not happen
|
|
}
|
|
|
|
// Store properties in $object
|
|
$object->setVarsFromFetchObj($obj);
|
|
|
|
// mode view kanban
|
|
if ($mode == 'kanban') {
|
|
if ($i == 0) {
|
|
print '<tr class="trkanban"><td colspan="'.$savnbfield.'">';
|
|
print '<div class="box-flex-container kanban">';
|
|
}
|
|
|
|
// TODO Use a cache for product
|
|
if (!empty($obj->fk_product)) {
|
|
$prod = new Product($db);
|
|
$prod->fetch($obj->fk_product);
|
|
} else {
|
|
$prod = null;
|
|
}
|
|
|
|
// Output Kanban
|
|
$selected = -1;
|
|
if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
|
|
$selected = 0;
|
|
if (in_array($object->id, $arrayofselected)) {
|
|
$selected = 1;
|
|
}
|
|
}
|
|
print $object->getKanbanView('', array('prod' => $prod, 'selected' => $selected));
|
|
if ($i == ($imaxinloop - 1)) {
|
|
print '</div>';
|
|
print '</td></tr>';
|
|
}
|
|
} else {
|
|
// Show line of result
|
|
$j = 0;
|
|
print '<tr data-rowid="'.$object->id.'" class="oddeven">';
|
|
// Action column
|
|
if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
|
|
print '<td class="nowrap center">';
|
|
if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
|
|
$selected = 0;
|
|
if (in_array($object->id, $arrayofselected)) {
|
|
$selected = 1;
|
|
}
|
|
print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
|
|
}
|
|
print '</td>';
|
|
if (!$i) {
|
|
$totalarray['nbfield']++;
|
|
}
|
|
}
|
|
foreach ($object->fields as $key => $val) {
|
|
$cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
|
|
if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'center';
|
|
} elseif ($key == 'status') {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'center';
|
|
}
|
|
|
|
if (in_array($val['type'], array('timestamp'))) {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'nowraponall';
|
|
} elseif ($key == 'ref') {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'nowraponall';
|
|
}
|
|
|
|
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'])) {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'right';
|
|
}
|
|
|
|
if (!empty($arrayfields['t.'.$key]['checked'])) {
|
|
print '<td'.($cssforfield ? ' class="'.$cssforfield.(preg_match('/tdoverflow/', $cssforfield) ? ' classfortooltip' : '').'"' : '');
|
|
if (preg_match('/tdoverflow/', $cssforfield) && !in_array($val['type'], array('ip', 'url')) && !is_numeric($object->$key)) {
|
|
print ' title="'.dol_escape_htmltag($object->$key).'"';
|
|
}
|
|
print '>';
|
|
if ($key == 'status') {
|
|
print $object->getLibStatut(5);
|
|
} elseif ($key == 'rowid') {
|
|
print $object->showOutputField($val, $key, $object->id, '');
|
|
} else {
|
|
print $object->showOutputField($val, $key, $object->$key, '');
|
|
}
|
|
print '</td>';
|
|
if (!$i) {
|
|
$totalarray['nbfield']++;
|
|
}
|
|
if (!empty($val['isameasure']) && $val['isameasure'] == 1) {
|
|
if (!$i) {
|
|
$totalarray['pos'][$totalarray['nbfield']] = 't.'.$key;
|
|
}
|
|
if (!isset($totalarray['val'])) {
|
|
$totalarray['val'] = array();
|
|
}
|
|
if (!isset($totalarray['val']['t.'.$key])) {
|
|
$totalarray['val']['t.'.$key] = 0;
|
|
}
|
|
$totalarray['val']['t.'.$key] += $object->$key;
|
|
}
|
|
}
|
|
}
|
|
// Extra fields
|
|
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
|
|
// Fields from hook
|
|
$parameters = array('arrayfields' => $arrayfields, 'object' => $object, 'obj' => $obj, 'i' => $i, 'totalarray' => &$totalarray);
|
|
$reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
print $hookmanager->resPrint;
|
|
// Action column
|
|
if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
|
|
print '<td class="nowrap center">';
|
|
if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
|
|
$selected = 0;
|
|
if (in_array($object->id, $arrayofselected)) {
|
|
$selected = 1;
|
|
}
|
|
print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
|
|
}
|
|
print '</td>';
|
|
if (!$i) {
|
|
$totalarray['nbfield']++;
|
|
}
|
|
}
|
|
|
|
print '</tr>'."\n";
|
|
}
|
|
|
|
$i++;
|
|
}
|
|
|
|
// Show total line
|
|
include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
|
|
|
|
|
|
// If no record found
|
|
if ($num == 0) {
|
|
$colspan = 1;
|
|
foreach ($arrayfields as $key => $val) {
|
|
if (!empty($val['checked'])) {
|
|
$colspan++;
|
|
}
|
|
}
|
|
print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
|
|
}
|
|
|
|
|
|
$db->free($resql);
|
|
|
|
$parameters = array('arrayfields' => $arrayfields, 'sql' => $sql);
|
|
$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
print $hookmanager->resPrint;
|
|
|
|
print '</table>'."\n";
|
|
print '</div>'."\n";
|
|
|
|
print '</form>'."\n";
|
|
|
|
|
|
if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
|
|
$hidegeneratedfilelistifempty = 1;
|
|
if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
|
|
$hidegeneratedfilelistifempty = 0;
|
|
}
|
|
|
|
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
|
|
$formfile = new FormFile($db);
|
|
|
|
// Show list of available documents
|
|
$urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
|
|
$urlsource .= str_replace('&', '&', $param);
|
|
|
|
$filedir = $diroutputmassaction;
|
|
$genallowed = $permissiontoread;
|
|
$delallowed = $permissiontoadd;
|
|
|
|
print $formfile->showdocuments('massfilesarea_bom', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
|
|
}
|
|
|
|
// End of page
|
|
llxFooter();
|
|
$db->close();
|