FIX Some fix on stock. Condition to view warehouse as column and
protection against infinite loop
This commit is contained in:
parent
9d3ad36b78
commit
2b6029f5d3
@ -2897,7 +2897,7 @@ class Product extends CommonObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reconstruit l'arborescence des categories sous la forme d'un tableau
|
* reconstruit l'arborescence des produits sous la forme d'un tableau
|
||||||
*
|
*
|
||||||
* @param int $multiply Because each sublevel must be multiplicated by parent nb
|
* @param int $multiply Because each sublevel must be multiplicated by parent nb
|
||||||
* @return array $this->res
|
* @return array $this->res
|
||||||
@ -2940,7 +2940,6 @@ class Product extends CommonObject
|
|||||||
* Return all Father products fo current product
|
* Return all Father products fo current product
|
||||||
*
|
*
|
||||||
* @return array Array of product
|
* @return array Array of product
|
||||||
* @see getParent
|
|
||||||
*/
|
*/
|
||||||
function getFather()
|
function getFather()
|
||||||
{
|
{
|
||||||
@ -2985,6 +2984,8 @@ class Product extends CommonObject
|
|||||||
*/
|
*/
|
||||||
function getChildsArbo($id, $firstlevelonly=0, $level=1)
|
function getChildsArbo($id, $firstlevelonly=0, $level=1)
|
||||||
{
|
{
|
||||||
|
global $alreadyfound;
|
||||||
|
|
||||||
$sql = "SELECT p.rowid, p.label as label, pa.qty as qty, pa.fk_product_fils as id, p.fk_product_type, pa.incdec";
|
$sql = "SELECT p.rowid, p.label as label, pa.qty as qty, pa.fk_product_fils as id, p.fk_product_type, pa.incdec";
|
||||||
$sql.= " FROM ".MAIN_DB_PREFIX."product as p";
|
$sql.= " FROM ".MAIN_DB_PREFIX."product as p";
|
||||||
$sql.= ", ".MAIN_DB_PREFIX."product_association as pa";
|
$sql.= ", ".MAIN_DB_PREFIX."product_association as pa";
|
||||||
@ -2994,6 +2995,7 @@ class Product extends CommonObject
|
|||||||
|
|
||||||
dol_syslog(get_class($this).'::getChildsArbo id='.$id.' level='.$level, LOG_DEBUG);
|
dol_syslog(get_class($this).'::getChildsArbo id='.$id.' level='.$level, LOG_DEBUG);
|
||||||
|
|
||||||
|
if ($level == 1) $alreadyfound=array($id=>1); // We init array of found object to start of tree, so if we found it later (should not happened), we stop immediatly
|
||||||
// Protection against infinite loop
|
// Protection against infinite loop
|
||||||
if ($level > 30) return array();
|
if ($level > 30) return array();
|
||||||
|
|
||||||
@ -3003,9 +3005,14 @@ class Product extends CommonObject
|
|||||||
$prods = array();
|
$prods = array();
|
||||||
while ($rec = $this->db->fetch_array($res))
|
while ($rec = $this->db->fetch_array($res))
|
||||||
{
|
{
|
||||||
// TODO Add check to not add ne record if already added
|
if (! empty($alreadyfound[$rec['rowid']]))
|
||||||
|
{
|
||||||
|
dol_syslog(get_class($this).'::getChildsArbo the product id='.$rec['rowid'].' was already found at a higher level in tree. We discard to avoid infinite loop', LOG_WARNING);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$alreadyfound[$rec['rowid']]=1;
|
||||||
$prods[$rec['rowid']]= array(
|
$prods[$rec['rowid']]= array(
|
||||||
0=>$rec['id'],
|
0=>$rec['rowid'],
|
||||||
1=>$rec['qty'],
|
1=>$rec['qty'],
|
||||||
2=>$rec['fk_product_type'],
|
2=>$rec['fk_product_type'],
|
||||||
3=>$this->db->escape($rec['label']),
|
3=>$this->db->escape($rec['label']),
|
||||||
@ -3015,7 +3022,7 @@ class Product extends CommonObject
|
|||||||
//$prods[$this->db->escape($rec['label'])]= array(0=>$rec['id'],1=>$rec['qty']);
|
//$prods[$this->db->escape($rec['label'])]= array(0=>$rec['id'],1=>$rec['qty']);
|
||||||
if (empty($firstlevelonly))
|
if (empty($firstlevelonly))
|
||||||
{
|
{
|
||||||
$listofchilds=$this->getChildsArbo($rec['id'], 0, $level + 1);
|
$listofchilds=$this->getChildsArbo($rec['rowid'], 0, $level + 1);
|
||||||
foreach($listofchilds as $keyChild => $valueChild)
|
foreach($listofchilds as $keyChild => $valueChild)
|
||||||
{
|
{
|
||||||
$prods[$rec['rowid']]['childs'][$keyChild] = $valueChild;
|
$prods[$rec['rowid']]['childs'][$keyChild] = $valueChild;
|
||||||
@ -3040,16 +3047,11 @@ class Product extends CommonObject
|
|||||||
*/
|
*/
|
||||||
function get_sousproduits_arbo()
|
function get_sousproduits_arbo()
|
||||||
{
|
{
|
||||||
//$parent = $this->getParent();
|
|
||||||
$parent=array();
|
$parent=array();
|
||||||
$parent[$this->label]=array(0 => $this->id);
|
|
||||||
|
|
||||||
foreach($parent as $key => $value) // key=label, value[0]=id
|
foreach($this->getChildsArbo($this->id) as $keyChild => $valueChild) // Warning. getChildsArbo can call getChildsArbo recursively. Starting point is $value[0]=id of product
|
||||||
{
|
{
|
||||||
foreach($this->getChildsArbo($value[0]) as $keyChild => $valueChild) // Warning. getChildsArbo can gell getChildsArbo recursively.
|
$parent[$this->label][$keyChild] = $valueChild;
|
||||||
{
|
|
||||||
$parent[$key][$keyChild] = $valueChild;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
foreach($parent as $key => $value) // key=label, value is array of childs
|
foreach($parent as $key => $value) // key=label, value is array of childs
|
||||||
{
|
{
|
||||||
|
|||||||
@ -235,8 +235,9 @@ if ($id > 0 || ! empty($ref))
|
|||||||
|
|
||||||
|
|
||||||
$prodsfather = $object->getFather(); // Parent Products
|
$prodsfather = $object->getFather(); // Parent Products
|
||||||
$object->get_sousproduits_arbo(); // Load $object->sousprod
|
$object->get_sousproduits_arbo(); // Load $object->sousprods
|
||||||
$prods_arbo=$object->get_arbo_each_prod();
|
$prods_arbo=$object->get_arbo_each_prod();
|
||||||
|
|
||||||
$nbofsubsubproducts=count($prods_arbo); // This include sub sub product into nb
|
$nbofsubsubproducts=count($prods_arbo); // This include sub sub product into nb
|
||||||
$prodschild = $object->getChildsArbo($id,1);
|
$prodschild = $object->getChildsArbo($id,1);
|
||||||
$nbofsubproducts=count($prodschild); // This include only first level of childs
|
$nbofsubproducts=count($prodschild); // This include only first level of childs
|
||||||
@ -379,10 +380,10 @@ if ($id > 0 || ! empty($ref))
|
|||||||
|
|
||||||
print '</tr>'."\n";
|
print '</tr>'."\n";
|
||||||
}
|
}
|
||||||
else // By default, we do not show this. It makes screen very difficult to understand
|
else
|
||||||
{
|
{
|
||||||
$hide='';
|
$hide='';
|
||||||
if (empty($conf->global->PRODUCT_SHOW_SUB_SUB_PRODUCTS)) $hide=' hideobject';
|
if (empty($conf->global->PRODUCT_SHOW_SUB_SUB_PRODUCTS)) $hide=' hideobject'; // By default, we do not show this. It makes screen very difficult to understand
|
||||||
|
|
||||||
$class=($class=='impair')?'pair':'impair';
|
$class=($class=='impair')?'pair':'impair';
|
||||||
print '<tr class="'.$class.$hide.'" id="sub-'.$value['id_parent'].'">';
|
print '<tr class="'.$class.$hide.'" id="sub-'.$value['id_parent'].'">';
|
||||||
@ -394,9 +395,13 @@ if ($id > 0 || ! empty($ref))
|
|||||||
print $productstatic->getNomUrl(1,'composition').'</td>';
|
print $productstatic->getNomUrl(1,'composition').'</td>';
|
||||||
print '<td>'.$productstatic->label.'</td>';
|
print '<td>'.$productstatic->label.'</td>';
|
||||||
|
|
||||||
|
// Best buying price
|
||||||
print '<td> </td>';
|
print '<td> </td>';
|
||||||
print '<td> </td>';
|
print '<td> </td>';
|
||||||
|
// Best selling price
|
||||||
|
print '<td> </td>';
|
||||||
|
print '<td> </td>';
|
||||||
|
|
||||||
if (! empty($conf->stock->enabled)) print '<td></td>'; // Real stock
|
if (! empty($conf->stock->enabled)) print '<td></td>'; // Real stock
|
||||||
print '<td align="center">'.$value['nb'].'</td>';
|
print '<td align="center">'.$value['nb'].'</td>';
|
||||||
print '<td> </td>';
|
print '<td> </td>';
|
||||||
|
|||||||
@ -145,7 +145,7 @@ $arrayfields=array(
|
|||||||
'p.label'=>array('label'=>$langs->trans("Label"), 'checked'=>1),
|
'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.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.duration'=>array('label'=>$langs->trans("Duration"), 'checked'=>($contextpage != 'productlist'), 'enabled'=>(! empty($conf->service->enabled))),
|
||||||
'p.sellprice'=>array('label'=>$titlesellprice, 'checked'=>1, 'enabled'=>empty($conf->global->PRODUIT_MULTIPRICES)),
|
'p.sellprice'=>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.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.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.desiredstock'=>array('label'=>$langs->trans("DesiredStock"), 'checked'=>1, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service')),
|
||||||
@ -425,7 +425,7 @@ else
|
|||||||
|
|
||||||
$varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage;
|
$varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage;
|
||||||
$selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
|
$selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
|
||||||
|
|
||||||
print '<table class="liste '.($moreforfilter?"listwithfilterbefore":"").'">';
|
print '<table class="liste '.($moreforfilter?"listwithfilterbefore":"").'">';
|
||||||
print '<tr class="liste_titre">';
|
print '<tr class="liste_titre">';
|
||||||
if (! empty($arrayfields['p.ref']['checked'])) print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER["PHP_SELF"],"p.ref","",$param,"",$sortfield,$sortorder);
|
if (! empty($arrayfields['p.ref']['checked'])) print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER["PHP_SELF"],"p.ref","",$param,"",$sortfield,$sortorder);
|
||||||
|
|||||||
@ -267,19 +267,16 @@ if ($resql)
|
|||||||
print_liste_field_titre($langs->trans("StockLimit"), $_SERVER["PHP_SELF"], "p.seuil_stock_alerte",$param,"",'align="right"',$sortfield,$sortorder);
|
print_liste_field_titre($langs->trans("StockLimit"), $_SERVER["PHP_SELF"], "p.seuil_stock_alerte",$param,"",'align="right"',$sortfield,$sortorder);
|
||||||
print_liste_field_titre($langs->trans("DesiredStock"), $_SERVER["PHP_SELF"], "p.desiredstock",$param,"",'align="right"',$sortfield,$sortorder);
|
print_liste_field_titre($langs->trans("DesiredStock"), $_SERVER["PHP_SELF"], "p.desiredstock",$param,"",'align="right"',$sortfield,$sortorder);
|
||||||
print_liste_field_titre($langs->trans("PhysicalStock"), $_SERVER["PHP_SELF"], "stock_physique",$param,"",'align="right"',$sortfield,$sortorder);
|
print_liste_field_titre($langs->trans("PhysicalStock"), $_SERVER["PHP_SELF"], "stock_physique",$param,"",'align="right"',$sortfield,$sortorder);
|
||||||
|
// Details per warehouse
|
||||||
/*
|
if (! empty($conf->global->STOCK_DETAIL_ON_WAREHOUSE)) // TODO This should be moved into the selection of fields on page product/list (page product/stock will be removed and replaced with product/list with its own context)
|
||||||
* Details per warehouse
|
{
|
||||||
*/
|
if ($nb_warehouse>1) {
|
||||||
|
foreach($warehouses_list as &$wh) {
|
||||||
if($nb_warehouse>1) {
|
print_liste_field_titre($wh['label'], '', '','','','align="right"');
|
||||||
|
}
|
||||||
foreach($warehouses_list as &$wh) {
|
|
||||||
print_liste_field_titre($wh['label'], '', '','','','align="right"');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($virtualdiffersfromphysical) print_liste_field_titre($langs->trans("VirtualStock"),$_SERVER["PHP_SELF"], "stock_theorique",$param,"",'align="right"',$sortfield,$sortorder);
|
if ($virtualdiffersfromphysical) print_liste_field_titre($langs->trans("VirtualStock"),$_SERVER["PHP_SELF"], "stock_theorique",$param,"",'align="right"',$sortfield,$sortorder);
|
||||||
print_liste_field_titre('');
|
print_liste_field_titre('');
|
||||||
print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Sell").')',$_SERVER["PHP_SELF"], "p.tosell",$param,"",'align="right"',$sortfield,$sortorder);
|
print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Sell").')',$_SERVER["PHP_SELF"], "p.tosell",$param,"",'align="right"',$sortfield,$sortorder);
|
||||||
@ -309,8 +306,8 @@ if ($resql)
|
|||||||
print '<td class="liste_titre"> </td>';
|
print '<td class="liste_titre"> </td>';
|
||||||
print '<td class="liste_titre" colspan="'.$colspan_warehouse.'"> </td>';
|
print '<td class="liste_titre" colspan="'.$colspan_warehouse.'"> </td>';
|
||||||
print '<td class="liste_titre" align="right">';
|
print '<td class="liste_titre" align="right">';
|
||||||
$searchpitco=$form->showFilterAndCheckAddButtons(0);
|
$searchpitco=$form->showFilterAndCheckAddButtons(0);
|
||||||
print $searchpitco;
|
print $searchpitco;
|
||||||
print '</td>';
|
print '</td>';
|
||||||
print '</tr>';
|
print '</tr>';
|
||||||
|
|
||||||
@ -349,19 +346,17 @@ if ($resql)
|
|||||||
print $objp->stock_physique;
|
print $objp->stock_physique;
|
||||||
print '</td>';
|
print '</td>';
|
||||||
|
|
||||||
/*
|
// Details per warehouse
|
||||||
* Details per warehouse
|
if (! empty($conf->global->STOCK_DETAIL_ON_WAREHOUSE)) // TODO This should be moved into the selection of fields on page product/list (page product/stock will be removed and replaced with product/list with its own context)
|
||||||
*/
|
{
|
||||||
|
if($nb_warehouse>1) {
|
||||||
if($nb_warehouse>1) {
|
foreach($warehouses_list as &$wh) {
|
||||||
|
|
||||||
foreach($warehouses_list as &$wh) {
|
print '<td align="right">';
|
||||||
|
print empty($product->stock_warehouse[$wh['id']]->real) ? '0' : $product->stock_warehouse[$wh['id']]->real;
|
||||||
print '<td align="right">';
|
print '</td>';
|
||||||
print empty($product->stock_warehouse[$wh['id']]->real) ? '0' : $product->stock_warehouse[$wh['id']]->real;
|
}
|
||||||
print '</td>';
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user