NEW fix listview class and add a demo for product list
This commit is contained in:
parent
043a26eeb5
commit
651ea92657
@ -39,6 +39,8 @@ class Listview
|
||||
$this->form = null;
|
||||
$this->totalRowToShow=0;
|
||||
$this->totalRow=0;
|
||||
|
||||
$this->TField=array();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -70,14 +72,15 @@ class Listview
|
||||
,'head_search'=>''
|
||||
,'export'=>array()
|
||||
,'view_type'=>''
|
||||
,'massactions'=>array()
|
||||
),$TParam['list']);
|
||||
|
||||
if (empty($TParam['limit'])) $TParam['limit'] = array();
|
||||
|
||||
$page = GETPOST('page');
|
||||
if (!empty($page)) $TParam['limit']['page'] = $page+1; // TODO dolibarr start page at 0 instead 1
|
||||
if (!empty($page)) $TParam['limit']['page'] = $page;
|
||||
|
||||
$TParam['limit'] = array_merge(array('page'=>1, 'nbLine' => $conf->liste_limit, 'global'=>0), $TParam['limit']);
|
||||
$TParam['limit'] = array_merge(array('page'=>0, 'nbLine' => $conf->liste_limit, 'global'=>0), $TParam['limit']);
|
||||
|
||||
if (GETPOST('sortfield'))
|
||||
{
|
||||
@ -137,17 +140,6 @@ class Listview
|
||||
|
||||
return $TKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param timestamp $date date to convert
|
||||
* @return int|string Date TMS or ''
|
||||
*/
|
||||
private function dateToSQLDate($date)
|
||||
{
|
||||
return $this->db->idate($date);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $TSQLMore contain some additional sql instructions
|
||||
* @param string $value date with read format
|
||||
@ -160,13 +152,11 @@ class Listview
|
||||
$TSQLDate=array();
|
||||
if(!empty($value['start']))
|
||||
{
|
||||
// $valueDeb = $this->dateToSQLDate($value['start'].' 00:00:00');
|
||||
$TSQLDate[]=$sKey." >= '".$value['start']."'" ;
|
||||
}
|
||||
|
||||
if(!empty($value['end']))
|
||||
{
|
||||
// $valueFin = $this->dateToSQLDate($value['end'].' 23:59:59');
|
||||
$TSQLDate[]=$sKey." <= '".$value['end']."'" ;
|
||||
}
|
||||
|
||||
@ -174,7 +164,6 @@ class Listview
|
||||
}
|
||||
else
|
||||
{
|
||||
// $value = $this->dateToSQLDate($value);
|
||||
$TSQLMore[]=$sKey." LIKE '".$value."%'" ;
|
||||
}
|
||||
}
|
||||
@ -227,9 +216,7 @@ class Listview
|
||||
*/
|
||||
private function search($sql, &$TParam)
|
||||
{
|
||||
$ListPOST = GETPOST('Listview');
|
||||
|
||||
if (!GETPOST("button_removefilter_x") && !GETPOST("button_removefilter.x") && !GETPOST("button_removefilter"))
|
||||
if (empty($TParam['no-auto-sql-search']) && !GETPOST("button_removefilter_x") && !GETPOST("button_removefilter.x") && !GETPOST("button_removefilter"))
|
||||
{
|
||||
foreach ($TParam['search'] as $field => $info)
|
||||
{
|
||||
@ -237,12 +224,14 @@ class Listview
|
||||
$TSQLMore = array();
|
||||
$allow_is_null = $this->getSearchNull($field,$TParam);
|
||||
|
||||
$fieldname = !empty($info['fieldname']) ? $info['fieldname'] : 'Listview_'.$this->id.'_search_'.$field;
|
||||
|
||||
foreach ($TsKey as $i => &$sKey)
|
||||
{
|
||||
$value = '';
|
||||
if (isset($ListPOST[$this->id]['search'][$field])) $value = $ListPOST[$this->id]['search'][$field];
|
||||
$value = GETPOST($fieldname);
|
||||
$value_null = GETPOST('Listview_'.$this->id.'_search_on_null_'.$field);
|
||||
|
||||
if ($allow_is_null && !empty($ListPOST[$this->id]['search_on_null'][$field]))
|
||||
if ($allow_is_null && !empty($value_null))
|
||||
{
|
||||
$TSQLMore[] = $sKey.' IS NULL ';
|
||||
$value = '';
|
||||
@ -250,7 +239,7 @@ class Listview
|
||||
|
||||
if (isset($TParam['type'][$field]) && ($TParam['type'][$field]==='date' || $TParam['type'][$field]==='datetime'))
|
||||
{
|
||||
$k = 'Listview_'.$this->id.'_search_'.$field;
|
||||
$k = $fieldname;
|
||||
if ($info['search_type'] === 'calendars')
|
||||
{
|
||||
$value = array();
|
||||
@ -296,25 +285,22 @@ class Listview
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$TField=array();
|
||||
$TField= & $this->TField;
|
||||
|
||||
$this->init($TParam);
|
||||
|
||||
$THeader = $this->initHeader($TParam);
|
||||
|
||||
$sql = $this->search($sql,$TParam);
|
||||
$sql.= $this->db->order($TParam['param']['sortfield'], $TParam['param']['sortorder']);
|
||||
|
||||
$nbtotalofrecords = '';
|
||||
$sql.= $this->db->order($TParam['sortfield'], $TParam['sortorder']);
|
||||
|
||||
if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
|
||||
{
|
||||
$result = $this->db->query($sql);
|
||||
$nbtotalofrecords = $this->db->num_rows($result);
|
||||
$this->totalRow = $this->db->num_rows($result);
|
||||
}
|
||||
$sql.= $this->db->plimit($TParam['param']['limit'] + 1, $TParam['param']['offset']);
|
||||
|
||||
$this->parse_sql($THeader, $TField, $TParam, $sql);
|
||||
|
||||
list($TTotal, $TTotalGroup)=$this->get_total($TField, $TParam);
|
||||
|
||||
return $this->renderList($THeader, $TField, $TTotal, $TTotalGroup, $TParam);
|
||||
@ -335,44 +321,42 @@ class Listview
|
||||
|
||||
$nb_search_in_bar = 0;
|
||||
|
||||
if(!empty($TParam['search']))
|
||||
foreach($THeader as $key => $libelle)
|
||||
{
|
||||
foreach($THeader as $key => $libelle)
|
||||
{
|
||||
if(empty($TSearch[$key]))$TSearch[$key]='';
|
||||
}
|
||||
}
|
||||
if(empty($TSearch[$key]))$TSearch[$key]='';
|
||||
}
|
||||
|
||||
$ListPOST = GETPOST('Listview');
|
||||
$removeFilter = (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETPOST("button_removefilter"));
|
||||
foreach($TParam['search'] as $key => $param_search)
|
||||
{
|
||||
$value = isset($ListPOST[$this->id]['search'][$key]) ? $ListPOST[$this->id]['search'][$key] : '';
|
||||
if ($removeFilter) $value = '';
|
||||
|
||||
$typeRecherche = (is_array($param_search) && isset($param_search['search_type'])) ? $param_search['search_type'] : $param_search;
|
||||
|
||||
$fieldname = !empty($param_search['fieldname']) ? $param_search['fieldname'] : 'Listview_'.$this->id.'_search_'.$key;
|
||||
$value = $removeFilter ? '' : GETPOST($fieldname);
|
||||
|
||||
if(is_array($typeRecherche))
|
||||
{
|
||||
$fsearch=$form->selectarray('Listview['.$this->id.'][search]['.$key.']', $typeRecherche,$value,1);
|
||||
$fsearch=$form->selectarray($fieldname, $typeRecherche,$value,1);
|
||||
}
|
||||
else if($typeRecherche==='calendar')
|
||||
{
|
||||
if (!$removeFilter) $value = GETPOST('Listview_'.$this->id.'_search_'.$key) ? mktime(0,0,0, (int) GETPOST('Listview_'.$this->id.'_search_'.$key.'month'), (int) GETPOST('Listview_'.$this->id.'_search_'.$key.'day'), (int) GETPOST('Listview_'.$this->id.'_search_'.$key.'year') ) : '';
|
||||
if (!$removeFilter) $value = GETPOST($fieldname) ? mktime(0,0,0, (int) GETPOST($fieldname.'month'), (int) GETPOST($fieldname.$key.'day'), (int) GETPOST($fieldname.'year') ) : '';
|
||||
|
||||
$fsearch = $form->select_date($value, 'Listview_'.$this->id.'_search_'.$key,0, 0, 1, "", 1, 0, 1);
|
||||
$fsearch = $form->select_date($value, $fieldname,0, 0, 1, "", 1, 0, 1);
|
||||
}
|
||||
else if($typeRecherche==='calendars')
|
||||
{
|
||||
$value_start = $value_end = '';
|
||||
if (!$removeFilter)
|
||||
{
|
||||
$value_start = GETPOST('Listview_'.$this->id.'_search_'.$key.'_start') ? mktime(0,0,0, (int) GETPOST('Listview_'.$this->id.'_search_'.$key.'_startmonth'), (int) GETPOST('Listview_'.$this->id.'_search_'.$key.'_startday'), (int) GETPOST('Listview_'.$this->id.'_search_'.$key.'_startyear') ) : '';
|
||||
$value_end = GETPOST('Listview_'.$this->id.'_search_'.$key.'_end') ? mktime(0,0,0, (int) GETPOST('Listview_'.$this->id.'_search_'.$key.'_endmonth'), (int) GETPOST('Listview_'.$this->id.'_search_'.$key.'_endday'), (int) GETPOST('Listview_'.$this->id.'_search_'.$key.'_endyear') ) : '';
|
||||
$value_start = GETPOST($fieldname.'_start') ? mktime(0,0,0, (int) GETPOST($fieldname.'_startmonth'), (int) GETPOST($fieldname.'_startday'), (int) GETPOST($fieldname.'_startyear') ) : '';
|
||||
$value_end = GETPOST($fieldname.'_end') ? mktime(0,0,0, (int) GETPOST($fieldname.'_endmonth'), (int) GETPOST($fieldname.'_endday'), (int) GETPOST($fieldname.'_endyear') ) : '';
|
||||
}
|
||||
|
||||
$fsearch = $form->select_date($value_start, 'Listview_'.$this->id.'_search_'.$key.'_start',0, 0, 1, "", 1, 0, 1)
|
||||
. $form->select_date($value_end, 'Listview_'.$this->id.'_search_'.$key.'_end',0, 0, 1, "", 1, 0, 1);
|
||||
$fsearch = $form->select_date($value_start,$fieldname.'_start',0, 0, 1, "", 1, 0, 1)
|
||||
. $form->select_date($value_end, $fieldname.'_end',0, 0, 1, "", 1, 0, 1);
|
||||
|
||||
}
|
||||
else if(is_string($typeRecherche))
|
||||
@ -381,13 +365,13 @@ class Listview
|
||||
}
|
||||
else
|
||||
{
|
||||
$fsearch='<input type="text" name="Listview['.$this->id.'][search]['.$key.']" id="Listview['.$this->id.'][search]['.$key.']" value="'.$value.'" size="15" />';
|
||||
$fsearch='<input type="text" name="'.$fieldname.'" id="'.$fieldname.'" value="'.$value.'" size="10" />';
|
||||
}
|
||||
|
||||
if(!empty($param_search['allow_is_null']))
|
||||
{
|
||||
$valueNull = isset($ListPOST[$this->id]['search_on_null'][$key]) ? 1 : 0;
|
||||
$fsearch.=' '.$form->checkbox1('', 'Listview['.$this->id.'][search_on_null]['.$key.']',1, $valueNull,' onclick=" if($(this).is(\':checked\')){ $(this).prev().val(\'\'); }" ').img_help(1, $langs->trans('SearchOnNUllValue'));
|
||||
$valueNull = GETPOST($fieldname.'search_on_null_'.$key) ? 1 : 0;
|
||||
$fsearch.=' '.$form->checkbox1('', $fieldname.'search_on_null_'.$key,1, $valueNull,' onclick=" if($(this).is(\':checked\')){ $(this).prev().val(\'\'); }" ').img_help(1, $langs->trans('SearchOnNUllValue'));
|
||||
}
|
||||
|
||||
if(!empty($THeader[$key]))
|
||||
@ -395,20 +379,10 @@ class Listview
|
||||
$TSearch[$key] = $fsearch;
|
||||
$nb_search_in_bar++;
|
||||
}
|
||||
else
|
||||
{
|
||||
$label = !empty($TParam['title'][$key]) ? $TParam['title'][$key] : $key ;
|
||||
$TParam['list']['head_search'].= '<th>'.$label.'</th>';
|
||||
// $TParam['list']['head_search'].='<div><span style="min-width:200px;display:inline-block;">'.$label.'</span> '.$fsearch.'</div>';
|
||||
}
|
||||
}
|
||||
|
||||
$search_button = ' <a href="#" onclick="Listview_submitSearch(this);" class="list-search-link">'.img_search().'</a>';
|
||||
|
||||
if(!empty($TParam['list']['head_search']))
|
||||
{
|
||||
$TParam['list']['head_search']='<div style="float:right;">'.$search_button.'</div>'.$TParam['list']['head_search'];
|
||||
}
|
||||
$search_button .= ' <a href="#" onclick="Listview_clearSearch(this);" class="list-search-link">'.img_searchclear().'</a>';
|
||||
|
||||
if($nb_search_in_bar>0)
|
||||
{
|
||||
@ -603,7 +577,7 @@ class Listview
|
||||
*/
|
||||
private function renderList(&$THeader, &$TField, &$TTotal, &$TTotalGroup, &$TParam)
|
||||
{
|
||||
global $bc;
|
||||
global $bc,$form;
|
||||
|
||||
$TSearch = $this->setSearch($THeader, $TParam);
|
||||
$TExport = $this->setExport($TParam, $TField, $THeader);
|
||||
@ -611,13 +585,24 @@ class Listview
|
||||
|
||||
//$out = $this->getJS();
|
||||
|
||||
$massactionbutton= empty($TParam['list']['massactions']) ? '' : $form->selectMassAction('', $TParam['list']['massactions']);
|
||||
|
||||
$dolibarr_decalage = $this->totalRow > $this->totalRowToShow ? 1 : 0;
|
||||
ob_start();
|
||||
print_barre_liste($TParam['list']['title'], $TParam['limit']['page']-1, $_SERVER["PHP_SELF"], '&'.$TParam['list']['param_url'], $TParam['sortfield'], $TParam['sortorder'], '', $this->totalRowToShow+$dolibarr_decalage, $this->totalRow, $TParam['list']['image'], 0, '', '', $TParam['limit']['nbLine']);
|
||||
print_barre_liste($TParam['list']['title'], $TParam['limit']['page'], $_SERVER["PHP_SELF"], '&'.$TParam['list']['param_url'], $TParam['sortfield'], $TParam['sortorder'], $massactionbutton, $this->totalRowToShow+$dolibarr_decalage, $this->totalRow, $TParam['list']['image'], 0, '', '', $TParam['limit']['nbLine']);
|
||||
$out .= ob_get_clean();
|
||||
|
||||
$classliste='liste';
|
||||
if(!empty($TParam['head_search'])) {
|
||||
$out.='<div class="liste_titre liste_titre_bydiv centpercent">';
|
||||
$out.=$TParam['head_search'];
|
||||
$out.='</div>';
|
||||
|
||||
$classliste.=' listwithfilterbefore';
|
||||
}
|
||||
|
||||
$out.= '<table id="'.$this->id.'" class="liste" width="100%"><thead>';
|
||||
$out.= '<div class="div-table-responsive">';
|
||||
$out.= '<table id="'.$this->id.'" class="'.$classliste.'" width="100%"><thead>';
|
||||
|
||||
if(count($TSearch)>0)
|
||||
{
|
||||
@ -627,12 +612,12 @@ class Listview
|
||||
{
|
||||
if ($field === 'selectedfields')
|
||||
{
|
||||
$out.= '<td class="liste_titre" align="right">'.$this->form->showFilterAndCheckAddButtons(0).'</td>';
|
||||
$out.= '<th class="liste_titre" align="right">'.$this->form->showFilterAndCheckAddButtons(0).'</th>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$moreattrib = 'style="width:'.$head['width'].';text-align:'.$head['text-align'].'"';
|
||||
$out .= '<td class="liste_titre" '.$moreattrib.'>'.$TSearch[$field].'</td>';
|
||||
$out .= '<th class="liste_titre" '.$moreattrib.'>'.$TSearch[$field].'</th>';
|
||||
}
|
||||
}
|
||||
|
||||
@ -646,10 +631,17 @@ class Listview
|
||||
$search = '';
|
||||
$prefix = '';
|
||||
|
||||
$label = $head['label'];
|
||||
|
||||
if ($field === 'selectedfields')
|
||||
{
|
||||
$moreattrib = 'align="right" ';
|
||||
$prefix = 'maxwidthsearch ';
|
||||
|
||||
if(!empty($TParam['list']['massactions'])) {
|
||||
$label.=$form->showCheckAddButtons('checkforselect', 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (empty($head['width'])) $head['width'] = 'auto';
|
||||
@ -662,10 +654,10 @@ class Listview
|
||||
else $search = $field;
|
||||
}
|
||||
|
||||
$out .= getTitleFieldOfList($head['label'], 0, $_SERVER["PHP_SELF"], $search, '', $moreparam, $moreattrib, $TParam['sortfield'], $TParam['sortorder'], $prefix);
|
||||
$out .= getTitleFieldOfList($label, 0, $_SERVER["PHP_SELF"], $search, '', $moreparam, $moreattrib, $TParam['sortfield'], $TParam['sortorder'], $prefix);
|
||||
$out .= $head['more'];
|
||||
}
|
||||
|
||||
|
||||
//$out .= '<th aligne="right" class="maxwidthsearch liste_titre">--</th>';
|
||||
$out .= '</tr>';
|
||||
|
||||
@ -673,23 +665,34 @@ class Listview
|
||||
|
||||
if(empty($TField))
|
||||
{
|
||||
if (!empty($TParam['list']['messageNothing'])) $out .= '<tr class="oddeven"><td colspan="'.(count($TParam['title'])+1).'"><span class="opacitymedium">'.$TParam['list']['messageNothing'].'</span></td></tr>';
|
||||
if (!empty($TParam['list']['messageNothing'])) $out .= '<tr class="oddeven"><td colspan="'.(count($THeader)+1).'"><span class="opacitymedium">'.$TParam['list']['messageNothing'].'</span></td></tr>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$var=true;
|
||||
$line_number = 0;
|
||||
foreach($TField as $fields)
|
||||
{
|
||||
if($this->in_view($TParam, $line_number))
|
||||
{
|
||||
$var=!$var;
|
||||
$out.='<tr '.$bc[$var].'> <!-- '.$field.' -->';
|
||||
$out.='<tr class="oddeven"> <!-- '.$field.' -->';
|
||||
|
||||
foreach ($THeader as $field => $head)
|
||||
{
|
||||
$value_aff =(isset($fields[$field]) ? $fields[$field] : ' ');
|
||||
|
||||
if ($field === 'selectedfields')
|
||||
{
|
||||
$head['text-align']='center';
|
||||
if(!empty($TParam['list']['massactions'])) {
|
||||
$arrayofselected=array(); // TODO get in param
|
||||
$selected=0;
|
||||
if (in_array($obj->rowid, $arrayofselected)) $selected=1;
|
||||
$value_aff.='<input id="cb'.$fields['rowid'].'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$fields['rowid'].'"'.($selected?' checked="checked"':'').'>';
|
||||
}
|
||||
}
|
||||
|
||||
$moreattrib = 'style="width:'.$head['width'].';text-align:'.$head['text-align'].'"';
|
||||
$out.='<td class="'.$field.'" '.$moreattrib.'>'.$fields[$field].'</td>';
|
||||
$out.='<td class="'.$field.'" '.$moreattrib.'>'.$value_aff.'</td>';
|
||||
}
|
||||
|
||||
$out.='</tr>';
|
||||
@ -718,6 +721,7 @@ class Listview
|
||||
}
|
||||
|
||||
$out .= '</table>';
|
||||
$out .= '</div>';
|
||||
|
||||
return $out;
|
||||
}
|
||||
@ -760,7 +764,7 @@ class Listview
|
||||
|
||||
foreach($TField as $row)
|
||||
{
|
||||
$this->set_line($TField, $TParam, $row);
|
||||
$this->set_line($THeader, $TField, $TParam, $row);
|
||||
}
|
||||
}
|
||||
|
||||
@ -778,7 +782,7 @@ class Listview
|
||||
}
|
||||
|
||||
$contextpage=md5($_SERVER['PHP_SELF']);
|
||||
if(!empty($TParam['allow-field-select']))
|
||||
if(!empty($TParam['allow-fields-select']))
|
||||
{
|
||||
$selectedfields = GETPOST('Listview'.$this->id.'_selectedfields');
|
||||
|
||||
@ -839,18 +843,25 @@ class Listview
|
||||
'order'=>(in_array($field, $TParam['orderby']['noOrder']) ? 0 : 1),
|
||||
'width'=>(!empty($TParam['size']['width'][$field]) ? $TParam['size']['width'][$field] : 'auto'),
|
||||
'text-align'=>(!empty($TParam['position']['text-align'][$field]) ? $TParam['position']['text-align'][$field] : 'auto'),
|
||||
'rank'=>(!empty($TParam['position']['rank'][$field]) ? $TParam['position']['rank'][$field] : 0),
|
||||
'more'=>''
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($selectedfields))
|
||||
{
|
||||
$THeader['selectedfields']['label']='<div style="float:right">'.$selectedfields.'</div>';
|
||||
}
|
||||
uasort($THeader,array('Listview','sortHeaderRank'));
|
||||
|
||||
$THeader['selectedfields']['label']=$selectedfields;
|
||||
|
||||
return $THeader;
|
||||
}
|
||||
|
||||
public function sortHeaderRank(&$a, &$b) {
|
||||
if($a['rank']>$b['rank']) return 1;
|
||||
else if($a['rank']<$b['rank']) return -1;
|
||||
else return 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $TParam TParam
|
||||
@ -874,11 +885,14 @@ class Listview
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $TField TField
|
||||
* @param string $TParam TParam
|
||||
* @param string $currentLine aaa
|
||||
* Apply function to result and set fields array
|
||||
*
|
||||
* @param string $THeader array of headers
|
||||
* @param string $TField array of fields
|
||||
* @param string $TParam array of parameters
|
||||
* @param string $currentLine object containing current sql result
|
||||
*/
|
||||
private function set_line(&$TField, &$TParam, $currentLine)
|
||||
private function set_line(&$THeader, &$TField, &$TParam, $currentLine)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
@ -887,16 +901,21 @@ class Listview
|
||||
if($this->in_view($TParam,$line_number))
|
||||
{
|
||||
$this->totalRowToShow++;
|
||||
$row=array(); $trans = array();
|
||||
foreach($currentLine as $field=>$value)
|
||||
$row=array();
|
||||
$trans = array();
|
||||
foreach($currentLine as $kF=>$vF)$trans['@'.$kF.'@'] = addslashes($vF);
|
||||
|
||||
foreach($THeader as $field=>$dummy)
|
||||
{
|
||||
$value = isset($currentLine->{$field}) ? $currentLine->{$field}: '';
|
||||
|
||||
if(is_object($value))
|
||||
{
|
||||
if(get_class($value)=='stdClass') {$value=print_r($value, true);}
|
||||
else $value=(string) $value;
|
||||
}
|
||||
|
||||
$trans['@'.$field.'@'] = $value;
|
||||
$trans['@'.$field.'@'] = addslashes($value);
|
||||
|
||||
if(!empty($TParam['math'][$field]))
|
||||
{
|
||||
@ -910,17 +929,19 @@ class Listview
|
||||
|
||||
if(isset($TParam['eval'][$field]) && in_array($field,array_keys($row)))
|
||||
{
|
||||
$strToEval = 'return '.strtr( $TParam['eval'][$field], array_merge( $trans, array('@val@'=>$row[$field]) )).';';
|
||||
$strToEval = 'return '.strtr( $TParam['eval'][$field], array_merge( $trans, array('@val@'=>addslashes( $row[$field] )) )).';';
|
||||
$row[$field] = eval($strToEval);
|
||||
|
||||
}
|
||||
|
||||
if(isset($TParam['type'][$field]) && !isset($TParam['eval'][$field]))
|
||||
{
|
||||
if($TParam['type'][$field]=='date' || $TParam['type'][$field]=='datetime' )
|
||||
{
|
||||
|
||||
if($row[$field] != '0000-00-00 00:00:00' && $row[$field] != '1000-01-01 00:00:00' && $row[$field] != '0000-00-00' && !empty($row[$field]))
|
||||
{
|
||||
if($TParam['type'][$field]=='datetime')$row[$field] = dol_print_date(strtotime($row[$field]),'dayhoursec');
|
||||
if($TParam['type'][$field]=='datetime')$row[$field] = dol_print_date(strtotime($row[$field]),'dayhour');
|
||||
else $row[$field] = dol_print_date(strtotime($row[$field]),'day');
|
||||
}
|
||||
else
|
||||
@ -996,6 +1017,8 @@ class Listview
|
||||
{
|
||||
$sql.=' LIMIT '.(int) $TParam['limit']['global'];
|
||||
}
|
||||
else if(!empty($TParam['limit'])) $sql.= $this->db->plimit($TParam['limit']['nbLine']+1, $TParam['limit']['page'] * $TParam['limit']['nbLine']);
|
||||
|
||||
|
||||
return $sql;
|
||||
}
|
||||
@ -1008,7 +1031,7 @@ class Listview
|
||||
*/
|
||||
private function parse_sql(&$THeader, &$TField, &$TParam, $sql)
|
||||
{
|
||||
$this->sql = $this->limitSQL($sql, $TParam);
|
||||
$this->sql = $this->limitSQL($sql, $TParam);
|
||||
|
||||
$this->TTotalTmp=array();
|
||||
$this->THideFlip = array_flip($TParam['hide']);
|
||||
@ -1016,12 +1039,13 @@ class Listview
|
||||
$res = $this->db->query($this->sql);
|
||||
if($res!==false)
|
||||
{
|
||||
$this->totalRow = $this->db->num_rows($res);
|
||||
dol_syslog(get_class($this)."::parse_sql id=".$this->id." sql=".$this->sql, LOG_DEBUG);
|
||||
|
||||
if(empty($this->totalRow))$this->totalRow = $this->db->num_rows($res);
|
||||
|
||||
while($currentLine = $this->db->fetch_object($res))
|
||||
{
|
||||
$this->set_line($TField, $TParam, $currentLine);
|
||||
$this->set_line($THeader, $TField, $TParam, $currentLine);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1029,4 +1053,23 @@ class Listview
|
||||
dol_syslog(get_class($this)."::parse_sql id=".$this->id." sql=".$this->sql, LOG_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
static function getCachedOjbect($class_name, $fk_object) {
|
||||
global $db, $TCacheListObject;
|
||||
|
||||
if(!class_exists($class_name)) return false;
|
||||
|
||||
if(empty($TCacheListObject)) $TCacheListObject = array();
|
||||
if(empty($TCacheListObject[$class_name])) $TCacheListObject[$class_name] =array();
|
||||
|
||||
if(empty($TCacheListObject[$class_name][$fk_object])) {
|
||||
$TCacheListObject[$class_name][$fk_object]= new $class_name($db);
|
||||
if( $TCacheListObject[$class_name][$fk_object]->fetch($fk_object)<0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $TCacheListObject[$class_name][$fk_object];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
702
htdocs/product/list-with-listview.php
Normal file
702
htdocs/product/list-with-listview.php
Normal file
@ -0,0 +1,702 @@
|
||||
<?php
|
||||
/* Copyright (C) 2001-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
|
||||
* Copyright (C) 2004-2016 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
|
||||
* Copyright (C) 2012-2016 Marcos García <marcosgdf@gmail.com>
|
||||
* Copyright (C) 2013-2016 Juanjo Menent <jmenent@2byte.es>
|
||||
* Copyright (C) 2013-2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
|
||||
* Copyright (C) 2013 Jean Heimburger <jean@tiaris.info>
|
||||
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
|
||||
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
|
||||
* Copyright (C) 2013 Adolfo segura <adolfo.segura@gmail.com>
|
||||
* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
|
||||
* Copyright (C) 2016 Ferran Marcet <fmarcet@2byte.es>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file htdocs/product/list.php
|
||||
* \ingroup produit
|
||||
* \brief Page to list products and services
|
||||
*/
|
||||
|
||||
require '../main.inc.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/product/inventory/listview.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
|
||||
if (! empty($conf->categorie->enabled))
|
||||
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
|
||||
|
||||
$langs->load("products");
|
||||
$langs->load("stocks");
|
||||
$langs->load("suppliers");
|
||||
$langs->load("companies");
|
||||
if (! empty($conf->productbatch->enabled)) $langs->load("productbatch");
|
||||
|
||||
$action=GETPOST('action','alpha');
|
||||
$massaction=GETPOST('massaction','alpha');
|
||||
$show_files=GETPOST('show_files','int');
|
||||
$confirm=GETPOST('confirm','alpha');
|
||||
$toselect = GETPOST('toselect', 'array');
|
||||
|
||||
$sref=GETPOST("sref");
|
||||
$sbarcode=GETPOST("sbarcode");
|
||||
$snom=GETPOST("snom");
|
||||
$sall=GETPOST("sall");
|
||||
$type= (int) GETPOST("type","int");
|
||||
$search_sale = GETPOST("search_sale");
|
||||
$search_categ = GETPOST("search_categ",'int');
|
||||
$tosell = GETPOST("tosell", 'int');
|
||||
$tobuy = GETPOST("tobuy", 'int');
|
||||
$fourn_id = GETPOST("fourn_id",'int');
|
||||
$catid = GETPOST('catid','int');
|
||||
$search_tobatch = GETPOST("search_tobatch",'int');
|
||||
$search_accountancy_code_sell = GETPOST("search_accountancy_code_sell",'alpha');
|
||||
$search_accountancy_code_buy = GETPOST("search_accountancy_code_buy",'alpha');
|
||||
$optioncss = GETPOST('optioncss','alpha');
|
||||
|
||||
//Show/hide child products. Hidden by default
|
||||
if (!$_POST) {
|
||||
$search_hidechildproducts = 'on';
|
||||
} else {
|
||||
$search_hidechildproducts = GETPOST('search_hidechildproducts');
|
||||
}
|
||||
|
||||
$diroutputmassaction=$conf->product->dir_output . '/temp/massgeneration/'.$user->id;
|
||||
|
||||
$limit = GETPOST("limit")?GETPOST("limit","int"):$conf->liste_limit;
|
||||
$sortfield = GETPOST("sortfield",'alpha');
|
||||
$sortorder = GETPOST("sortorder",'alpha');
|
||||
$page = (GETPOST("page",'int')?GETPOST("page", 'int'):0);
|
||||
if ($page == -1) { $page = 0; }
|
||||
$offset = $limit * $page;
|
||||
$pageprev = $page - 1;
|
||||
$pagenext = $page + 1;
|
||||
if (! $sortfield) $sortfield="p.ref";
|
||||
if (! $sortorder) $sortorder="ASC";
|
||||
|
||||
// Initialize context for list
|
||||
$contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'productservicelist';
|
||||
if ((string) $type == '1') { $contextpage='servicelist'; if ($search_type=='') $search_type='1'; }
|
||||
if ((string) $type == '0') { $contextpage='productlist'; if ($search_type=='') $search_type='0'; }
|
||||
|
||||
// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array
|
||||
$hookmanager->initHooks(array($contextpage));
|
||||
$extrafields = new ExtraFields($db);
|
||||
$form=new Form($db);
|
||||
|
||||
// fetch optionals attributes and labels
|
||||
$extralabels = $extrafields->fetch_name_optionals_label('product');
|
||||
$search_array_options=$extrafields->getOptionalsFromPost($extralabels,'','search_');
|
||||
|
||||
if (empty($action)) $action='list';
|
||||
|
||||
// Get object canvas (By default, this is not defined, so standard usage of dolibarr)
|
||||
$canvas=GETPOST("canvas");
|
||||
$objcanvas=null;
|
||||
if (! empty($canvas))
|
||||
{
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/canvas.class.php';
|
||||
$objcanvas = new Canvas($db,$action);
|
||||
$objcanvas->getCanvas('product','list',$canvas);
|
||||
}
|
||||
|
||||
// Security check
|
||||
if ($type=='0') $result=restrictedArea($user,'produit','','','','','',$objcanvas);
|
||||
else if ($type=='1') $result=restrictedArea($user,'service','','','','','',$objcanvas);
|
||||
else $result=restrictedArea($user,'produit|service','','','','','',$objcanvas);
|
||||
|
||||
// Define virtualdiffersfromphysical
|
||||
$virtualdiffersfromphysical=0;
|
||||
if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER))
|
||||
{
|
||||
$virtualdiffersfromphysical=1; // According to increase/decrease stock options, virtual and physical stock may differs.
|
||||
}
|
||||
|
||||
// List of fields to search into when doing a "search in all"
|
||||
$fieldstosearchall = array(
|
||||
'p.ref'=>"Ref",
|
||||
'pfp.ref_fourn'=>"RefSupplier",
|
||||
'p.label'=>"ProductLabel",
|
||||
'p.description'=>"Description",
|
||||
"p.note"=>"Note",
|
||||
);
|
||||
// multilang
|
||||
if (! empty($conf->global->MAIN_MULTILANGS))
|
||||
{
|
||||
$fieldstosearchall['pl.label']='ProductLabelTranslated';
|
||||
$fieldstosearchall['pl.description']='ProductDescriptionTranslated';
|
||||
$fieldstosearchall['pl.note']='ProductNoteTranslated';
|
||||
}
|
||||
if (! empty($conf->barcode->enabled)) {
|
||||
$fieldstosearchall['p.barcode']='Gencod';
|
||||
}
|
||||
|
||||
if (empty($conf->global->PRODUIT_MULTIPRICES))
|
||||
{
|
||||
$titlesellprice=$langs->trans("SellingPrice");
|
||||
if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
|
||||
{
|
||||
$titlesellprice=$form->textwithpicto($langs->trans("SellingPrice"), $langs->trans("DefaultPriceRealPriceMayDependOnCustomer"));
|
||||
}
|
||||
}
|
||||
|
||||
// Definition of fields for lists
|
||||
$arrayfields=array(
|
||||
'p.ref'=>array('label'=>$langs->trans("Ref"), 'checked'=>1),
|
||||
//'pfp.ref_fourn'=>array('label'=>$langs->trans("RefSupplier"), 'checked'=>1, 'enabled'=>(! empty($conf->barcode->enabled))),
|
||||
'p.label'=>array('label'=>$langs->trans("Label"), 'checked'=>1),
|
||||
'p.barcode'=>array('label'=>$langs->trans("Gencod"), 'checked'=>($contextpage != 'servicelist'), 'enabled'=>(! empty($conf->barcode->enabled))),
|
||||
'p.duration'=>array('label'=>$langs->trans("Duration"), 'checked'=>($contextpage != 'productlist'), 'enabled'=>(! empty($conf->service->enabled))),
|
||||
'p.price'=>array('label'=>$langs->trans("SellingPrice"), 'checked'=>1, 'enabled'=>empty($conf->global->PRODUIT_MULTIPRICES)),
|
||||
'p.minbuyprice'=>array('label'=>$langs->trans("BuyingPriceMinShort"), 'checked'=>1, 'enabled'=>(! empty($user->rights->fournisseur->lire))),
|
||||
'p.seuil_stock_alerte'=>array('label'=>$langs->trans("StockLimit"), 'checked'=>0, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service')),
|
||||
'p.desiredstock'=>array('label'=>$langs->trans("DesiredStock"), 'checked'=>1, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service')),
|
||||
'p.stock'=>array('label'=>$langs->trans("PhysicalStock"), 'checked'=>1, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service')),
|
||||
'stock_virtual'=>array('label'=>$langs->trans("VirtualStock"), 'checked'=>1, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service' && $virtualdiffersfromphysical)),
|
||||
'p.tobatch'=>array('label'=>$langs->trans("ManageLotSerial"), 'checked'=>0, 'enabled'=>(! empty($conf->productbatch->enabled))),
|
||||
'p.accountancy_code_sell'=>array('label'=>$langs->trans("ProductAccountancySellCode"), 'checked'=>0),
|
||||
'p.accountancy_code_buy'=>array('label'=>$langs->trans("ProductAccountancyBuyCode"), 'checked'=>0),
|
||||
'p.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
|
||||
'p.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500),
|
||||
'p.tosell'=>array('label'=>$langs->trans("Status").' ('.$langs->trans("Sell").')', 'checked'=>1, 'position'=>1000),
|
||||
'p.tobuy'=>array('label'=>$langs->trans("Status").' ('.$langs->trans("Buy").')', 'checked'=>1, 'position'=>1000)
|
||||
);
|
||||
// Extra fields
|
||||
if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
|
||||
{
|
||||
foreach($extrafields->attribute_label as $key => $val)
|
||||
{
|
||||
$arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Actions
|
||||
*/
|
||||
|
||||
if (GETPOST('cancel')) { $action='list'; $massaction=''; }
|
||||
if (! GETPOST('confirmmassaction') && $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") || GETPOST("button_removefilter.x") || GETPOST("button_removefilter")) // All tests are required to be compatible with all browsers
|
||||
{
|
||||
$sall="";
|
||||
$sref="";
|
||||
$snom="";
|
||||
$sbarcode="";
|
||||
$search_categ=0;
|
||||
$tosell="";
|
||||
$tobuy="";
|
||||
$search_tobatch='';
|
||||
$search_accountancy_code_sell='';
|
||||
$search_accountancy_code_buy='';
|
||||
$search_array_options=array();
|
||||
}
|
||||
|
||||
// Mass actions
|
||||
$objectclass='Product';
|
||||
if ((string) $type == '1') { $objectlabel='Services'; }
|
||||
if ((string) $type == '0') { $objectlabel='Products'; }
|
||||
|
||||
$permtoread = $user->rights->produit->lire;
|
||||
$permtodelete = $user->rights->produit->supprimer;
|
||||
$uploaddir = $conf->product->dir_output;
|
||||
include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* View
|
||||
*/
|
||||
|
||||
$htmlother=new FormOther($db);
|
||||
|
||||
if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action))
|
||||
{
|
||||
$objcanvas->assign_values($action); // This must contains code to load data (must call LoadListDatas($limit, $offset, $sortfield, $sortorder))
|
||||
$objcanvas->display_canvas($action); // This is code to show template
|
||||
}
|
||||
else
|
||||
{
|
||||
$title=$langs->trans("ProductsAndServices");
|
||||
|
||||
if (isset($type))
|
||||
{
|
||||
if ($type==1)
|
||||
{
|
||||
$texte = $langs->trans("Services");
|
||||
}
|
||||
else
|
||||
{
|
||||
$texte = $langs->trans("Products");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$texte = $langs->trans("ProductsAndServices");
|
||||
}
|
||||
|
||||
$sql = 'SELECT DISTINCT p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity,';
|
||||
$sql.= ' p.fk_product_type, p.duration, p.tosell, p.tobuy, p.seuil_stock_alerte, p.desiredstock,';
|
||||
$sql.= ' p.tobatch, p.accountancy_code_sell, p.accountancy_code_buy,';
|
||||
$sql.= ' p.datec, p.tms,';
|
||||
//$sql.= ' pfp.ref_fourn as ref_supplier, ';
|
||||
$sql.= ' MIN(pfp.unitprice) as minsellprice';
|
||||
if (!empty($conf->variants->enabled) && $search_hidechildproducts && ($type === 0)) {
|
||||
$sql .= ', pac.rowid prod_comb_id';
|
||||
}
|
||||
// Add fields from extrafields
|
||||
foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key.' as options_'.$key : '');
|
||||
// Add fields from hooks
|
||||
$parameters=array();
|
||||
$reshook=$hookmanager->executeHooks('printFieldListSelect',$parameters); // Note that $action and $object may have been modified by hook
|
||||
$sql.=$hookmanager->resPrint;
|
||||
$sql.= ' FROM '.MAIN_DB_PREFIX.'product as p';
|
||||
if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_extrafields as ef on (p.rowid = ef.fk_object)";
|
||||
if (! empty($search_categ) || ! empty($catid)) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_product as cp ON p.rowid = cp.fk_product"; // We'll need this table joined to the select in order to filter by categ
|
||||
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product";
|
||||
// multilang
|
||||
if (! empty($conf->global->MAIN_MULTILANGS)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_lang as pl ON pl.fk_product = p.rowid AND pl.lang = '".$langs->getDefaultLang() ."'";
|
||||
if (!empty($conf->variants->enabled) && $search_hidechildproducts && ($type === 0)) {
|
||||
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_combination pac ON pac.fk_product_child = p.rowid";
|
||||
}
|
||||
|
||||
$sql.= ' WHERE p.entity IN ('.getEntity('product', 1).')';
|
||||
if ($sall) $sql .= natural_search(array_keys($fieldstosearchall), $sall);
|
||||
// if the type is not 1, we show all products (type = 0,2,3)
|
||||
if (dol_strlen($type))
|
||||
{
|
||||
if ($type == 1) $sql.= " AND p.fk_product_type = '1'";
|
||||
else $sql.= " AND p.fk_product_type <> '1'";
|
||||
}
|
||||
if ($sref) $sql .= natural_search('p.ref', $sref);
|
||||
if ($snom) $sql .= natural_search('p.label', $snom);
|
||||
if ($sbarcode) $sql .= natural_search('p.barcode', $sbarcode);
|
||||
if (isset($tosell) && dol_strlen($tosell) > 0 && $tosell!=-1) $sql.= " AND p.tosell = ".$db->escape($tosell);
|
||||
if (isset($tobuy) && dol_strlen($tobuy) > 0 && $tobuy!=-1) $sql.= " AND p.tobuy = ".$db->escape($tobuy);
|
||||
if (dol_strlen($canvas) > 0) $sql.= " AND p.canvas = '".$db->escape($canvas)."'";
|
||||
if ($catid > 0) $sql.= " AND cp.fk_categorie = ".$catid;
|
||||
if ($catid == -2) $sql.= " AND cp.fk_categorie IS NULL";
|
||||
if ($search_categ > 0) $sql.= " AND cp.fk_categorie = ".$db->escape($search_categ);
|
||||
if ($search_categ == -2) $sql.= " AND cp.fk_categorie IS NULL";
|
||||
if ($fourn_id > 0) $sql.= " AND pfp.fk_soc = ".$fourn_id;
|
||||
if ($search_tobatch != '' && $search_tobatch >= 0) $sql.= " AND p.tobatch = ".$db->escape($search_tobatch);
|
||||
if ($search_accountancy_code_sell) $sql.= natural_search('p.accountancy_code_sell', $search_accountancy_code_sell);
|
||||
if ($search_accountancy_code_sell) $sql.= natural_search('p.accountancy_code_buy', $search_accountancy_code_buy);
|
||||
// Add where from extra fields
|
||||
|
||||
if (!empty($conf->variants->enabled) && $search_hidechildproducts && ($type === 0)) {
|
||||
$sql .= " AND pac.rowid IS NULL";
|
||||
}
|
||||
|
||||
// Add where from extra fields
|
||||
foreach ($search_array_options as $key => $val)
|
||||
{
|
||||
$crit=$val;
|
||||
$tmpkey=preg_replace('/search_options_/','',$key);
|
||||
$typ=$extrafields->attribute_type[$tmpkey];
|
||||
$mode=0;
|
||||
if (in_array($typ, array('int','double'))) $mode=1; // Search on a numeric
|
||||
if ($val && ( ($crit != '' && ! in_array($typ, array('select'))) || ! empty($crit)))
|
||||
{
|
||||
$sql .= natural_search('ef.'.$tmpkey, $crit, $mode);
|
||||
}
|
||||
}
|
||||
// Add where from hooks
|
||||
$parameters=array();
|
||||
$reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // Note that $action and $object may have been modified by hook
|
||||
$sql.=$hookmanager->resPrint;
|
||||
$sql.= " GROUP BY p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type,";
|
||||
$sql.= " p.fk_product_type, p.duration, p.tosell, p.tobuy, p.seuil_stock_alerte, p.desiredstock,";
|
||||
$sql.= ' p.datec, p.tms, p.entity, p.tobatch, p.accountancy_code_sell, p.accountancy_code_buy';
|
||||
if (!empty($conf->variants->enabled) && $search_hidechildproducts && ($type === 0)) {
|
||||
$sql .= ', pac.rowid';
|
||||
}
|
||||
// Add fields from extrafields
|
||||
foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key : '');
|
||||
// Add fields from hooks
|
||||
$parameters=array();
|
||||
$reshook=$hookmanager->executeHooks('printFieldSelect',$parameters); // Note that $action and $object may have been modified by hook
|
||||
$sql.=$hookmanager->resPrint;
|
||||
|
||||
// TODO put these functions into product.lib.php if this go from demo to core
|
||||
/**
|
||||
* Function return formated sell price
|
||||
*
|
||||
* @param int $fk_object rowid of product
|
||||
* @return string
|
||||
*/
|
||||
function list_get_product_sellprice($fk_object) {
|
||||
global $langs,$conf, $user;
|
||||
|
||||
$object = Listview::getCachedOjbect('Product', $fk_object);
|
||||
if($object === false) return '';
|
||||
|
||||
if ($object->status)
|
||||
{
|
||||
if ($object->price_base_type == 'TTC') return price($object->price_ttc).' '.$langs->trans("TTC");
|
||||
else return price($object->price).' '.$langs->trans("HT");
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Function return formated product status sell or buy
|
||||
*
|
||||
* @param int $fk_object rowid of product
|
||||
* @param string $field concerned field status|status_buy
|
||||
* @param int $type for libstatus
|
||||
* @return string
|
||||
*/
|
||||
function list_get_product_status($fk_object, $field, $type) {
|
||||
global $conf, $user;
|
||||
|
||||
$object = Listview::getCachedOjbect('Product', $fk_object);
|
||||
|
||||
if($object === false) return '';
|
||||
|
||||
if (! empty($conf->use_javascript_ajax) && $user->rights->produit->creer && ! empty($conf->global->MAIN_DIRECT_STATUS_UPDATE)) {
|
||||
return ajax_object_onoff($object, 'status', 'tosell', 'ProductStatusOnSell', 'ProductStatusNotOnSell');
|
||||
} else {
|
||||
return $object->LibStatut($object->{$field},5,$type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function return formated ref
|
||||
*
|
||||
* @param int $fk_object rowid of product
|
||||
* @return string
|
||||
*/
|
||||
function list_get_product_ref($fk_object) {
|
||||
global $conf, $user;
|
||||
|
||||
$object = Listview::getCachedOjbect('Product', $fk_object);
|
||||
|
||||
if($object === false) return '';
|
||||
|
||||
return $object->getNomUrl(1,'',24);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function return formated extrafield
|
||||
*
|
||||
* @param int $fk_object rowid of product
|
||||
* @param string $key extrafield to output
|
||||
* @return string
|
||||
*/
|
||||
function list_get_product_extrafield($fk_object, $key) {
|
||||
global $extrafields;
|
||||
|
||||
$object = Listview::getCachedOjbect('Product', $fk_object);
|
||||
if($object === false) return '';
|
||||
|
||||
return $extrafields->showOutputField($key, $object->array_options['options_'.$key], '', 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function return formated virtual stock
|
||||
*
|
||||
* @param int $fk_object rowid of product
|
||||
* @return string
|
||||
*/
|
||||
function list_get_product_virtual_stock($fk_object) {
|
||||
global $langs;
|
||||
|
||||
$object = Listview::getCachedOjbect('Product', $fk_object);
|
||||
if($object === false) return '';
|
||||
|
||||
$object->load_stock('nobatch');
|
||||
|
||||
$out = '';
|
||||
if ($object->type != 1)
|
||||
{
|
||||
if ($object->seuil_stock_alerte != '' && $object->stock_theorique < (float) $object->seuil_stock_alerte) $out.= img_warning($langs->trans("StockTooLow")).' ';
|
||||
$out.= $object->stock_theorique;
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function return formated stock
|
||||
*
|
||||
* @param int $fk_object rowid of product
|
||||
* @return string
|
||||
*/
|
||||
function list_get_product_stock($fk_object) {
|
||||
global $langs;
|
||||
|
||||
$object = Listview::getCachedOjbect('Product', $fk_object);
|
||||
if($object === false) return '';
|
||||
|
||||
$out = '';
|
||||
if ($object->type != 1)
|
||||
{
|
||||
if ($object->seuil_stock_alerte != '' && $object->stock_reel< (float) $object->seuil_stock_alerte) $out.= img_warning($langs->trans("StockTooLow")).' ';
|
||||
$out.= (double)$object->stock_reel;
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
/**
|
||||
* Function return formated min buy price
|
||||
*
|
||||
* @param int $fk_object rowid of product
|
||||
* @return string
|
||||
*/
|
||||
function list_get_product_minbuyprice($fk_object) {
|
||||
global $conf, $user, $langs,$db,$form;
|
||||
|
||||
$out = '';
|
||||
|
||||
$object = Listview::getCachedOjbect('Product', $fk_object);
|
||||
if($object === false || empty($object->status_buy) ) return '';
|
||||
|
||||
$product_fourn =new ProductFournisseur($db);
|
||||
if ($product_fourn->find_min_price_product_fournisseur($fk_object) > 0)
|
||||
{
|
||||
if ($product_fourn->product_fourn_price_id > 0)
|
||||
{
|
||||
if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->lire)
|
||||
{
|
||||
$htmltext=$product_fourn->display_price_product_fournisseur(1, 1, 0, 1);
|
||||
$out.= $form->textwithpicto(price($product_fourn->fourn_unitprice).' '.$langs->trans("HT"),$htmltext);
|
||||
}
|
||||
else $out.= price($product_fourn->fourn_unitprice).' '.$langs->trans("HT");
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
// array of customized field function
|
||||
$arrayeval = array(
|
||||
'tobuy'=>'list_get_product_status(@rowid@, "status_buy",1)'
|
||||
,'tosell'=>'list_get_product_status(@rowid@, "status",0)'
|
||||
,'ref'=>'list_get_product_ref(@rowid@)'
|
||||
,'label'=>'dol_trunc("@val@",40)'
|
||||
,'price'=>'list_get_product_sellprice(@rowid@)'
|
||||
,'stock_virtual'=>'list_get_product_virtual_stock(@rowid@)'
|
||||
,'stock'=>'list_get_product_stock(@rowid@)'
|
||||
,'minbuyprice'=>'list_get_product_minbuyprice(@rowid@)'
|
||||
);
|
||||
|
||||
// defined list align for field
|
||||
$arrayalign = array(
|
||||
'price'=>'right'
|
||||
,'tobuy'=>'right'
|
||||
,'tosell'=>'right'
|
||||
,'desiredstock'=>'right'
|
||||
,'stock'=>'right'
|
||||
,'stock_virtual'=>'right'
|
||||
,'minbuyprice'=>'right'
|
||||
,'datec'=>'center'
|
||||
,'tms'=>'center'
|
||||
);
|
||||
|
||||
$parameters=array('arrayfields'=>$arrayfields);
|
||||
$reshook=$hookmanager->executeHooks('printFieldListMoreFields',$parameters); // Note that $action and $object may have been modified by hook
|
||||
if($reshook) {
|
||||
$arrayfields = $hookmanager->resArray;
|
||||
}
|
||||
|
||||
// init title, hidden field (allowed into selected fields), and position
|
||||
$arrayhide = $arraytitle = $arrayposition = array();
|
||||
foreach($arrayfields as $k=>$data) {
|
||||
if(!isset($data['enabled']) || $data['enabled']) {
|
||||
list($t,$f) = explode('.',$k);
|
||||
if(empty($f))$f = $k;
|
||||
$arraytitle[$f]=$data['label'];
|
||||
if(empty($data['checked'])) $arrayhide[] = $f;
|
||||
$arrayposition[$f] = empty($data['position']) ? 0 : $data['position'];
|
||||
}
|
||||
}
|
||||
|
||||
// Extra fields
|
||||
if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
|
||||
{
|
||||
foreach($extrafields->attribute_label as $key => $val)
|
||||
{
|
||||
$arrayalign[$key]=$extrafields->getAlignFlag($key);
|
||||
$arrayeval[$key] = 'list_get_product_extrafield(@rowid@, "'.$key.'")';
|
||||
}
|
||||
}
|
||||
// List of mass actions available
|
||||
$arrayofmassactions = array(
|
||||
//'presend'=>$langs->trans("SendByMail"),
|
||||
//'builddoc'=>$langs->trans("PDFMerge"),
|
||||
);
|
||||
if ($user->rights->produit->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete");
|
||||
if ($massaction == 'presend' || $massaction == 'createbills') $arrayofmassactions=array();
|
||||
|
||||
// Filter on categories
|
||||
$moreforfilter='';
|
||||
if (! empty($conf->categorie->enabled))
|
||||
{
|
||||
$moreforfilter.='<div class="divsearchfield">';
|
||||
$moreforfilter.=$langs->trans('Categories'). ': ';
|
||||
$moreforfilter.=$htmlother->select_categories(Categorie::TYPE_PRODUCT,$search_categ,'search_categ',1);
|
||||
$moreforfilter.='</div>';
|
||||
}
|
||||
|
||||
//Show/hide child products. Hidden by default
|
||||
if (!empty($conf->variants->enabled) && $type === 0) {
|
||||
$moreforfilter.='<div class="divsearchfield">';
|
||||
$moreforfilter.= '<input type="checkbox" id="search_hidechildproducts" name="search_hidechildproducts" value="on"'.($search_hidechildproducts ? 'checked="checked"' : '').'>';
|
||||
$moreforfilter.= ' <label for="search_hidechildproducts">'.$langs->trans('HideChildProducts').'</label>';
|
||||
$moreforfilter.='</div>';
|
||||
}
|
||||
|
||||
if ($moreforfilter)
|
||||
{
|
||||
$parameters=array();
|
||||
$reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters); // Note that $action and $object may have been modified by hook
|
||||
|
||||
if(!empty($hookmanager->resPrint)) {
|
||||
$moreforfilter.=$hookmanager->resPrint;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$param='';
|
||||
if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.urlencode($contextpage);
|
||||
if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.urlencode($limit);
|
||||
if ($search_categ > 0) $param.="&search_categ=".urlencode($search_categ);
|
||||
if ($sref) $param="&sref=".urlencode($sref);
|
||||
if ($search_ref_supplier) $param="&search_ref_supplier=".urlencode($search_ref_supplier);
|
||||
if ($sbarcode) $param.=($sbarcode?"&sbarcode=".urlencode($sbarcode):"");
|
||||
if ($snom) $param.="&snom=".urlencode($snom);
|
||||
if ($sall) $param.="&sall=".urlencode($sall);
|
||||
if ($tosell != '') $param.="&tosell=".urlencode($tosell);
|
||||
if ($tobuy != '') $param.="&tobuy=".urlencode($tobuy);
|
||||
if ($fourn_id > 0) $param.=($fourn_id?"&fourn_id=".$fourn_id:"");
|
||||
if ($seach_categ) $param.=($search_categ?"&search_categ=".urlencode($search_categ):"");
|
||||
if ($type != '') $param.='&type='.urlencode($type);
|
||||
if ($optioncss != '') $param.='&optioncss='.urlencode($optioncss);
|
||||
if ($search_tobatch) $param="&search_ref_supplier=".urlencode($search_ref_supplier);
|
||||
if ($search_accountancy_code_sell) $param="&search_accountancy_code_sell=".urlencode($search_accountancy_code_sell);
|
||||
if ($search_accountancy_code_buy) $param="&search_accountancy_code_buy=".urlencode($search_accountancy_code_buy);
|
||||
// Add $param from extra fields
|
||||
foreach ($search_array_options as $key => $val)
|
||||
{
|
||||
$crit=$val;
|
||||
$tmpkey=preg_replace('/search_options_/','',$key);
|
||||
if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val);
|
||||
}
|
||||
|
||||
//var_dump($arraytitle,$arrayhide);
|
||||
$list=new Listview($db, 'products');
|
||||
$listHTML = $list->render($sql,array(
|
||||
'list'=>array(
|
||||
'title'=>$texte
|
||||
,'image'=>'title_products.png'
|
||||
,'massactions'=>$arrayofmassactions
|
||||
,'param_url'=>$param
|
||||
,'messageNothing'=>''
|
||||
)
|
||||
,'limit'=>array(
|
||||
'nbLine'=>$limit
|
||||
)
|
||||
,'sortfield'=>$sortfield
|
||||
,'sortorder'=>$sortorder
|
||||
,'title'=>$arraytitle // column definition title (only defined where abble to show)
|
||||
,'position'=>array(
|
||||
'text-align'=>$arrayalign
|
||||
,'rank'=>$arrayposition
|
||||
)
|
||||
,'allow-fields-select'=>1 // allow to select hidden fields
|
||||
,'head_search'=>$moreforfilter //custom search on head
|
||||
,'no-auto-sql-search'=>1 //disabled auto completion sql for search and pager url, use dolibarr style for migration of product list
|
||||
,'translate'=>array()
|
||||
,'search'=>array(
|
||||
'ref'=>array('search_type'=>true, 'table'=>'p', 'fieldname'=>'sref')
|
||||
,'label'=>array('search_type'=>true, 'table'=>'p', 'fieldname'=>'snom')
|
||||
,'tosell'=>array('search_type'=> array('0'=>$langs->trans('ProductStatusNotOnSellShort'),'1'=>$langs->trans('ProductStatusOnSellShort')), 'fieldname'=>'tosell')
|
||||
,'tobuy'=>array('search_type'=> array('0'=>$langs->trans('ProductStatusNotOnBuyShort'),'1'=>$langs->trans('ProductStatusOnBuyShort')), 'fieldname'=>'tobuy')
|
||||
,'barcode'=>array('search_type'=>true, 'table'=>'p', 'fieldname'=>'sbarcode')
|
||||
,'accountancy_code_sell'=>array('search_type'=>true, 'table'=>'p', 'fieldname'=>'search_accountancy_code_sell')
|
||||
,'accountancy_code_buy'=>array('search_type'=>true, 'table'=>'p', 'fieldname'=>'search_accountancy_code_buy')
|
||||
)
|
||||
,'type'=>array(
|
||||
'datec'=>'datetime'
|
||||
,'tms'=>'datetime'
|
||||
)
|
||||
,'hide'=>$arrayhide
|
||||
,'eval'=>$arrayeval
|
||||
));
|
||||
|
||||
$num = $list->totalRow;
|
||||
|
||||
$arrayofselected=is_array($toselect)?$toselect:array();
|
||||
|
||||
if ($num == 1 && ! empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $sall)
|
||||
{
|
||||
$id = $list->TField[0]->rowid;
|
||||
header("Location: ".DOL_URL_ROOT.'/product/card.php?id='.$id);
|
||||
exit;
|
||||
}
|
||||
|
||||
$helpurl='';
|
||||
if (isset($type))
|
||||
{
|
||||
if ($type == 0)
|
||||
{
|
||||
$helpurl='EN:Module_Products|FR:Module_Produits|ES:Módulo_Productos';
|
||||
}
|
||||
else if ($type == 1)
|
||||
{
|
||||
$helpurl='EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios';
|
||||
}
|
||||
}
|
||||
|
||||
llxHeader('',$title,$helpurl,'');
|
||||
|
||||
// Displays product removal confirmation
|
||||
if (GETPOST('delprod')) {
|
||||
setEventMessages($langs->trans("ProductDeleted", GETPOST('delprod')), null, 'mesgs');
|
||||
}
|
||||
|
||||
print '<form action="'.$_SERVER["PHP_SELF"].'" method="post" name="formulaire">';
|
||||
if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
|
||||
print '<input type="hidden" name="token" value="'.$_SESSION['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="type" value="'.$type.'">';
|
||||
|
||||
echo $listHTML;
|
||||
|
||||
print '</form>';
|
||||
|
||||
}
|
||||
|
||||
|
||||
llxFooter();
|
||||
$db->close();
|
||||
Loading…
Reference in New Issue
Block a user