From 2ef0e95586410cf7bf840ccb25cd9fc5f4f1c372 Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Thu, 11 Oct 2018 12:08:50 +0200 Subject: [PATCH 1/6] New: works with variants: - If product is parent showing stock of childs and not itself - Add function hasVariants for know if product has variants --- htdocs/product/class/product.class.php | 19 + htdocs/product/stock/product.php | 790 ++++++++++-------- .../class/ProductCombination.class.php | 2 +- 3 files changed, 451 insertions(+), 360 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 050d756ad82..3257f9bbde5 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -3493,6 +3493,25 @@ class Product extends CommonObject return $nb; } + /** + * Return if a product has variants or not + * + * @return int Number of variants + */ + function hasVariants() { + $nb = 0; + $sql = "SELECT count(rowid) as nb FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE fk_product_parent = ".$this->id; + $sql.= " AND entity IN (".getEntity('product').")"; + + $resql = $this->db->query($sql); + if ($resql) { + $obj = $this->db->fetch_object($resql); + if ($obj) $nb = $obj->nb; + } + + return $nb; + } + /** * Return all parent products for current product (first level only) * diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php index 324e14047d4..51871736a3d 100644 --- a/htdocs/product/stock/product.php +++ b/htdocs/product/stock/product.php @@ -45,6 +45,13 @@ if (! empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; } +if (! empty($conf->variants->enabled)) { + require_once DOL_DOCUMENT_ROOT . '/variants/class/ProductAttribute.class.php'; + require_once DOL_DOCUMENT_ROOT . '/variants/class/ProductAttributeValue.class.php'; + require_once DOL_DOCUMENT_ROOT . '/variants/class/ProductCombination.class.php'; + require_once DOL_DOCUMENT_ROOT . '/variants/class/ProductCombination2ValuePair.class.php'; +} + // Load translation files required by the page $langs->loadlangs(array('products', 'orders', 'bills', 'stocks', 'sendings')); if (! empty($conf->productbatch->enabled)) $langs->load("productbatch"); @@ -518,6 +525,8 @@ if ($id > 0 || $ref) $object = new Product($db); $result = $object->fetch($id,$ref); + $variants = $object->hasVariants(); + $object->load_stock(); $title = $langs->trans('ProductServiceCard'); @@ -558,174 +567,161 @@ if ($id > 0 || $ref) print '
'; print ''; - if ($conf->productbatch->enabled) - { - print ''; - } + if (! $variants) { - // PMP - print ''; - print ''; - print ''; + if ($conf->productbatch->enabled) { + print ''; + } - // Minimum Price - print ''; - print ''; + // PMP + print ''; + print ''; + print ''; - if (empty($conf->global->PRODUIT_MULTIPRICES)) - { - // Price - print ''; + print ''; - // Price minimum - print ''; + + // Price minimum + print ''; } else { - print price($object->price_min) . ' ' . $langs->trans($object->price_base_type); + // Price + print ''; + + // Price minimum + print ''; } - print ''; - } - else - { - // Price - print ''; - // Price minimum - print ''; + + // Real stock + $text_stock_options = $langs->trans("RealStockDesc") . '
'; + $text_stock_options .= $langs->trans("RealStockWillAutomaticallyWhen") . '
'; + $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || !empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE) ? $langs->trans("DeStockOnShipment") . '
' : ''); + $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) ? $langs->trans("DeStockOnValidateOrder") . '
' : ''); + $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_BILL) ? $langs->trans("DeStockOnBill") . '
' : ''); + $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL) ? $langs->trans("ReStockOnBill") . '
' : ''); + $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER) ? $langs->trans("ReStockOnValidateOrder") . '
' : ''); + $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER) ? $langs->trans("ReStockOnDispatchOrder") . '
' : ''); + print ''; + print ''; + print ''; + + $stocktheo = price2num($object->stock_theorique, 'MS'); + + $found = 0; + $helpondiff = '' . $langs->trans("StockDiffPhysicTeoric") . ':
'; + // Number of customer orders running + if (!empty($conf->commande->enabled)) { + if ($found) $helpondiff .= '
'; else $found = 1; + $helpondiff .= $langs->trans("ProductQtyInCustomersOrdersRunning") . ': ' . $object->stats_commande['qty']; + $result = $object->load_stats_commande(0, '0', 1); + if ($result < 0) dol_print_error($db, $object->error); + $helpondiff .= ' (' . $langs->trans("ProductQtyInDraft") . ': ' . $object->stats_commande['qty'] . ')'; + } + + // Number of product from customer order already sent (partial shipping) + if (!empty($conf->expedition->enabled)) { + if ($found) $helpondiff .= '
'; else $found = 1; + $result = $object->load_stats_sending(0, '2', 1); + $helpondiff .= $langs->trans("ProductQtyInShipmentAlreadySent") . ': ' . $object->stats_expedition['qty']; + } + + // Number of supplier order running + if (!empty($conf->fournisseur->enabled)) { + if ($found) $helpondiff .= '
'; else $found = 1; + $result = $object->load_stats_commande_fournisseur(0, '3,4', 1); + $helpondiff .= $langs->trans("ProductQtyInSuppliersOrdersRunning") . ': ' . $object->stats_commande_fournisseur['qty']; + $result = $object->load_stats_commande_fournisseur(0, '0,1,2', 1); + if ($result < 0) dol_print_error($db, $object->error); + $helpondiff .= ' (' . $langs->trans("ProductQtyInDraftOrWaitingApproved") . ': ' . $object->stats_commande_fournisseur['qty'] . ')'; + } + + // Number of product from supplier order already received (partial receipt) + if (!empty($conf->fournisseur->enabled)) { + if ($found) $helpondiff .= '
'; else $found = 1; + $helpondiff .= $langs->trans("ProductQtyInSuppliersShipmentAlreadyRecevied") . ': ' . $object->stats_reception['qty']; + } + + // Calculating a theorical value + print ''; + print "'; + print ''; + + // Last movement + $sql = "SELECT max(m.datem) as datem"; + $sql .= " FROM " . MAIN_DB_PREFIX . "stock_mouvement as m"; + $sql .= " WHERE m.fk_product = '" . $object->id . "'"; + $resqlbis = $db->query($sql); + if ($resqlbis) { + $obj = $db->fetch_object($resqlbis); + $lastmovementdate = $db->jdate($obj->datem); + } else { + dol_print_error($db); + } + print '"; } - - // Stock alert threshold - print ''; - - // Hook formObject - $parameters=array(); - $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - - // Desired stock - print ''; - - // Real stock - $text_stock_options = $langs->trans("RealStockDesc").'
'; - $text_stock_options.= $langs->trans("RealStockWillAutomaticallyWhen").'
'; - $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)?$langs->trans("DeStockOnShipment").'
':''); - $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER)?$langs->trans("DeStockOnValidateOrder").'
':''); - $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_BILL)?$langs->trans("DeStockOnBill").'
':''); - $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL)?$langs->trans("ReStockOnBill").'
':''); - $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER)?$langs->trans("ReStockOnValidateOrder").'
':''); - $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)?$langs->trans("ReStockOnDispatchOrder").'
':''); - print ''; - print ''; - print ''; - - $stocktheo = price2num($object->stock_theorique, 'MS'); - - $found=0; - $helpondiff=''.$langs->trans("StockDiffPhysicTeoric").':
'; - // Number of customer orders running - if (! empty($conf->commande->enabled)) - { - if ($found) $helpondiff.='
'; else $found=1; - $helpondiff.=$langs->trans("ProductQtyInCustomersOrdersRunning").': '.$object->stats_commande['qty']; - $result=$object->load_stats_commande(0,'0', 1); - if ($result < 0) dol_print_error($db,$object->error); - $helpondiff.=' ('.$langs->trans("ProductQtyInDraft").': '.$object->stats_commande['qty'].')'; - } - - // Number of product from customer order already sent (partial shipping) - if (! empty($conf->expedition->enabled)) - { - if ($found) $helpondiff.='
'; else $found=1; - $result=$object->load_stats_sending(0,'2', 1); - $helpondiff.=$langs->trans("ProductQtyInShipmentAlreadySent").': '.$object->stats_expedition['qty']; - } - - // Number of supplier order running - if (! empty($conf->fournisseur->enabled)) - { - if ($found) $helpondiff.='
'; else $found=1; - $result=$object->load_stats_commande_fournisseur(0,'3,4', 1); - $helpondiff.=$langs->trans("ProductQtyInSuppliersOrdersRunning").': '.$object->stats_commande_fournisseur['qty']; - $result=$object->load_stats_commande_fournisseur(0,'0,1,2', 1); - if ($result < 0) dol_print_error($db,$object->error); - $helpondiff.=' ('.$langs->trans("ProductQtyInDraftOrWaitingApproved").': '.$object->stats_commande_fournisseur['qty'].')'; - } - - // Number of product from supplier order already received (partial receipt) - if (! empty($conf->fournisseur->enabled)) - { - if ($found) $helpondiff.='
'; else $found=1; - $helpondiff.=$langs->trans("ProductQtyInSuppliersShipmentAlreadyRecevied").': '.$object->stats_reception['qty']; - } - - // Calculating a theorical value - print ''; - print "'; - print ''; - - // Last movement - $sql = "SELECT max(m.datem) as datem"; - $sql.= " FROM ".MAIN_DB_PREFIX."stock_mouvement as m"; - $sql.= " WHERE m.fk_product = '".$object->id."'"; - $resqlbis = $db->query($sql); - if ($resqlbis) - { - $obj = $db->fetch_object($resqlbis); - $lastmovementdate=$db->jdate($obj->datem); - } - else - { - dol_print_error($db); - } - print '"; - print "
'.$langs->trans("ManageLotSerial").''; - print $object->getLibStatut(0,2); - print '
'.$langs->trans("AverageUnitPricePMP").''; - if ($object->pmp > 0) print price($object->pmp).' '.$langs->trans("HT"); - print '
' . $langs->trans("ManageLotSerial") . ''; + print $object->getLibStatut(0, 2); + print '
'.$langs->trans("BuyingPriceMin").''; - $product_fourn = new ProductFournisseur($db); - if ($product_fourn->find_min_price_product_fournisseur($object->id) > 0) - { - if ($product_fourn->product_fourn_price_id > 0) print $product_fourn->display_price_product_fournisseur(); - else print $langs->trans("NotDefined"); - } - print '
' . $langs->trans("AverageUnitPricePMP") . ''; + if ($object->pmp > 0) print price($object->pmp) . ' ' . $langs->trans("HT"); + print '
' . $langs->trans("SellingPrice") . ''; - if ($object->price_base_type == 'TTC') { - print price($object->price_ttc) . ' ' . $langs->trans($object->price_base_type); - } else { - print price($object->price) . ' ' . $langs->trans($object->price_base_type); + // Minimum Price + print '
' . $langs->trans("BuyingPriceMin") . ''; + $product_fourn = new ProductFournisseur($db); + if ($product_fourn->find_min_price_product_fournisseur($object->id) > 0) { + if ($product_fourn->product_fourn_price_id > 0) print $product_fourn->display_price_product_fournisseur(); + else print $langs->trans("NotDefined"); } print '
' . $langs->trans("MinPrice") . ''; - if ($object->price_base_type == 'TTC') { - print price($object->price_min_ttc) . ' ' . $langs->trans($object->price_base_type); + if (empty($conf->global->PRODUIT_MULTIPRICES)) { + // Price + print '
' . $langs->trans("SellingPrice") . ''; + if ($object->price_base_type == 'TTC') { + print price($object->price_ttc) . ' ' . $langs->trans($object->price_base_type); + } else { + print price($object->price) . ' ' . $langs->trans($object->price_base_type); + } + print '
' . $langs->trans("MinPrice") . ''; + if ($object->price_base_type == 'TTC') { + print price($object->price_min_ttc) . ' ' . $langs->trans($object->price_base_type); + } else { + print price($object->price_min) . ' ' . $langs->trans($object->price_base_type); + } + print '
' . $langs->trans("SellingPrice") . ''; + print $langs->trans("Variable"); + print '
' . $langs->trans("MinPrice") . ''; + print $langs->trans("Variable"); + print '
' . $langs->trans("SellingPrice") . ''; - print $langs->trans("Variable"); + + // Stock alert threshold + print '
' . $form->editfieldkey($form->textwithpicto($langs->trans("StockLimit"), $langs->trans("StockLimitDesc"), 1), 'seuil_stock_alerte', $object->seuil_stock_alerte, $object, $user->rights->produit->creer) . ''; + print $form->editfieldval("StockLimit", 'seuil_stock_alerte', $object->seuil_stock_alerte, $object, $user->rights->produit->creer, 'string'); print '
' . $langs->trans("MinPrice") . ''; - print $langs->trans("Variable"); + // Hook formObject + $parameters = array(); + $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + + // Desired stock + print '
' . $form->editfieldkey($form->textwithpicto($langs->trans("DesiredStock"), $langs->trans("DesiredStockDesc"), 1), 'desiredstock', $object->desiredstock, $object, $user->rights->produit->creer); + print ''; + print $form->editfieldval("DesiredStock", 'desiredstock', $object->desiredstock, $object, $user->rights->produit->creer, 'string'); print '
'; + print $form->textwithpicto($langs->trans("PhysicalStock"), $text_stock_options, 1); + print '' . price2num($object->stock_reel, 'MS'); + if ($object->seuil_stock_alerte != '' && ($object->stock_reel < $object->seuil_stock_alerte)) print ' ' . img_warning($langs->trans("StockLowerThanLimit", $object->seuil_stock_alerte)); + print '
'; + print $form->textwithpicto($langs->trans("VirtualStock"), $langs->trans("VirtualStockDesc")); + print '"; + //print (empty($stocktheo)?0:$stocktheo); + print $form->textwithpicto((empty($stocktheo) ? 0 : $stocktheo), $helpondiff); + if ($object->seuil_stock_alerte != '' && ($object->stock_theorique < $object->seuil_stock_alerte)) print ' ' . img_warning($langs->trans("StockLowerThanLimit", $object->seuil_stock_alerte)); + print '
' . $langs->trans("LastMovement") . ''; + if ($lastmovementdate) { + print dol_print_date($lastmovementdate, 'dayhour') . ' '; + print '(' . $langs->trans("FullList") . ')'; + } else { + print '' . $langs->trans("None") . ''; + } + print "
'.$form->editfieldkey($form->textwithpicto($langs->trans("StockLimit"), $langs->trans("StockLimitDesc"), 1),'seuil_stock_alerte',$object->seuil_stock_alerte,$object,$user->rights->produit->creer).''; - print $form->editfieldval("StockLimit",'seuil_stock_alerte',$object->seuil_stock_alerte,$object,$user->rights->produit->creer,'string'); - print '
'.$form->editfieldkey($form->textwithpicto($langs->trans("DesiredStock"), $langs->trans("DesiredStockDesc"), 1),'desiredstock',$object->desiredstock,$object,$user->rights->produit->creer); - print ''; - print $form->editfieldval("DesiredStock",'desiredstock',$object->desiredstock,$object,$user->rights->produit->creer,'string'); - print '
'; - print $form->textwithpicto($langs->trans("PhysicalStock"), $text_stock_options, 1); - print ''.price2num($object->stock_reel, 'MS'); - if ($object->seuil_stock_alerte != '' && ($object->stock_reel < $object->seuil_stock_alerte)) print ' '.img_warning($langs->trans("StockLowerThanLimit", $object->seuil_stock_alerte)); - print '
'; - print $form->textwithpicto($langs->trans("VirtualStock"), $langs->trans("VirtualStockDesc")); - print '"; - //print (empty($stocktheo)?0:$stocktheo); - print $form->textwithpicto((empty($stocktheo)?0:$stocktheo), $helpondiff); - if ($object->seuil_stock_alerte != '' && ($object->stock_theorique < $object->seuil_stock_alerte)) print ' '.img_warning($langs->trans("StockLowerThanLimit", $object->seuil_stock_alerte)); - print '
'.$langs->trans("LastMovement").''; - if ($lastmovementdate) - { - print dol_print_date($lastmovementdate,'dayhour').' '; - print '('.$langs->trans("FullList").')'; - } - else - { - print ''.$langs->trans("None").''; - } - print "
"; print ''; @@ -770,229 +766,305 @@ if (empty($reshook)) { print "
\n"; - if ($user->rights->stock->mouvement->creer) - { - print ''.$langs->trans("CorrectStock").''; - } + if (! $variants) { - //if (($user->rights->stock->mouvement->creer) && ! $object->hasbatch()) - if ($user->rights->stock->mouvement->creer) - { - print ''.$langs->trans("TransferStock").''; + if ($user->rights->stock->mouvement->creer) { + print '' . $langs->trans("CorrectStock") . ''; + } + + //if (($user->rights->stock->mouvement->creer) && ! $object->hasbatch()) + if ($user->rights->stock->mouvement->creer) { + print '' . $langs->trans("TransferStock") . ''; + } } - print '
'; } } -/* - * Stock detail (by warehouse). May go down into batch details. - */ +if (! $variants) { + /* + * Stock detail (by warehouse). May go down into batch details. + */ -print '
'; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -if ((! empty($conf->productbatch->enabled)) && $object->hasbatch()) -{ - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; -} - -$sql = "SELECT e.rowid, e.ref as label, e.lieu, ps.reel, ps.rowid as product_stock_id, p.pmp"; -$sql.= " FROM ".MAIN_DB_PREFIX."entrepot as e,"; -$sql.= " ".MAIN_DB_PREFIX."product_stock as ps"; -$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = ps.fk_product"; -$sql.= " WHERE ps.reel != 0"; -$sql.= " AND ps.fk_entrepot = e.rowid"; -$sql.= " AND e.entity IN (".getEntity('stock').")"; -$sql.= " AND ps.fk_product = ".$object->id; -$sql.= " ORDER BY e.ref"; - -$entrepotstatic=new Entrepot($db); -$product_lot_static=new Productlot($db); - -$total=0; -$totalvalue=$totalvaluesell=0; - -$resql=$db->query($sql); -if ($resql) -{ - $num = $db->num_rows($resql); - $total=$totalwithpmp; - $i=0; $var=false; - while ($i < $num) - { - $obj = $db->fetch_object($resql); - $entrepotstatic->id=$obj->rowid; - $entrepotstatic->libelle=$obj->label; - $entrepotstatic->lieu=$obj->lieu; - $stock_real = price2num($obj->reel, 'MS'); - print ''; - print ''; - print ''; - // PMP - print ''; - // Value purchase - print ''; - // Sell price - print ''; - // Value sell - print ''; - else print $langs->trans("Variable"); - print ''; ; - $total += $obj->reel; - if (price2num($object->pmp)) $totalwithpmp += $obj->reel; - $totalvalue = $totalvalue + ($object->pmp*$obj->reel); - $totalvaluesell = $totalvaluesell + ($object->price*$obj->reel); - // Batch Detail - if ((! empty($conf->productbatch->enabled)) && $object->hasbatch()) - { - $details=Productbatch::findAll($db, $obj->product_stock_id, 0, $object->id); - if ($details<0) dol_print_error($db); - foreach ($details as $pdluo) - { - $product_lot_static->id = $pdluo->lotid; - $product_lot_static->batch = $pdluo->batch; - $product_lot_static->eatby = $pdluo->eatby; - $product_lot_static->sellby = $pdluo->sellby; - - if ($action == 'editline' && GETPOST('lineid','int') == $pdluo->id) - { //Current line edit - print "\n".''; - print ''; - } - else - { - print "\n".''; - print ''; - print ''; - print ''; - print ''; - print ''; - } - } - } - $i++; - - } -} -else dol_print_error($db); - -print ''; -print ''; -print ''; -// Value purchase -print ''; -print ''; -// Value to sell -print ''; -print ""; -print "
'.$langs->trans("Warehouse").''.$langs->trans("NumberOfUnit").''.$langs->trans("AverageUnitPricePMPShort").''.$langs->trans("EstimatedStockValueShort").''.$langs->trans("SellPriceMin").''.$langs->trans("EstimatedStockValueSellShort").'
'.$langs->trans("batch_number").''.$langs->trans("EatByDate").''.$langs->trans("SellByDate").'
'.$entrepotstatic->getNomUrl(1).''.$stock_real.($stock_real < 0 ?' '.img_warning():'').''.(price2num($object->pmp)?price2num($object->pmp,'MU'):'').''.(price2num($object->pmp)?price(price2num($object->pmp*$obj->reel,'MT')):'').''; - if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($object->price,'MU'),1); - else print $langs->trans("Variable"); - print ''; - if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($object->price*$obj->reel,'MT'),1).'
'; - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print '
'; - print $form->selectDate($pdluo->eatby,'eatby','','',1,'',1,0); - print ''; - print $form->selectDate($pdluo->sellby,'sellby','','',1,'',1,0); - print ''.$pdluo->qty.($pdluo->qty<0?' '.img_warning():'').''; - print '
'; - print '
'; - print '
'; - print img_picto($langs->trans("Tranfer"),'uparrow','class="hideonsmartphone"').' '; - print 'id.'">'.$langs->trans("TransferStock").''; - // Disabled, because edition of stock content must use the "Correct stock menu". - // Do not use this, or data will be wrong (bad tracking of movement label, inventory code, ... - //print 'id.'#'.$pdluo->id.'">'; - //print img_edit().''; - print $product_lot_static->getNomUrl(1); - print ''. dol_print_date($pdluo->eatby,'day') .''. dol_print_date($pdluo->sellby,'day') .''.$pdluo->qty.($pdluo->qty<0?' '.img_warning():'').'
'.$langs->trans("Total").':'.price2num($total, 'MS').''; -print ($totalwithpmp?price(price2num($totalvalue/$totalwithpmp,'MU')):' '); // This value may have rounding errors -print ''; -print $totalvalue?price(price2num($totalvalue,'MT'),1):' '; -print ''; -if (empty($conf->global->PRODUIT_MULTIPRICES)) print ($total?price($totalvaluesell/$total,1):' '); -else print $langs->trans("Variable"); -print ''; -if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($totalvaluesell,'MT'),1); -else print $langs->trans("Variable"); -print '
"; -print '
'; - -if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE)) -{ - print '

'; - print_titre($langs->trans('AddNewProductStockWarehouse')); - - if (!empty($user->rights->produit->creer)){ - print '
'; - print ''; - print ''; - } + print '
'; print ''; - if (!empty($user->rights->produit->creer)){ - print ''; - print ''; - print ''; - print ''; - print ''; - }else{ - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if ((!empty($conf->productbatch->enabled)) && $object->hasbatch()) { + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; print ''; } - $pse = new ProductStockEntrepot($db); - $lines = $pse->fetchAll($id); + $sql = "SELECT e.rowid, e.ref as label, e.lieu, ps.reel, ps.rowid as product_stock_id, p.pmp"; + $sql .= " FROM " . MAIN_DB_PREFIX . "entrepot as e,"; + $sql .= " " . MAIN_DB_PREFIX . "product_stock as ps"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product as p ON p.rowid = ps.fk_product"; + $sql .= " WHERE ps.reel != 0"; + $sql .= " AND ps.fk_entrepot = e.rowid"; + $sql .= " AND e.entity IN (" . getEntity('stock') . ")"; + $sql .= " AND ps.fk_product = " . $object->id; + $sql .= " ORDER BY e.ref"; - if (!empty($lines)) - { - $var=false; - foreach($lines as $line) - { - $ent = new Entrepot($db); - $ent->fetch($line['fk_entrepot']); - print ''; - print ''; - print ''; - if (!empty($user->rights->produit->creer)){ - print ''; + $entrepotstatic = new Entrepot($db); + $product_lot_static = new Productlot($db); + + $total = 0; + $totalvalue = $totalvaluesell = 0; + + $resql = $db->query($sql); + if ($resql) { + $num = $db->num_rows($resql); + $total = $totalwithpmp; + $i = 0; + $var = false; + while ($i < $num) { + $obj = $db->fetch_object($resql); + $entrepotstatic->id = $obj->rowid; + $entrepotstatic->libelle = $obj->label; + $entrepotstatic->lieu = $obj->lieu; + $stock_real = price2num($obj->reel, 'MS'); + print ''; + print ''; + print ''; + // PMP + print ''; + // Value purchase + print ''; + // Sell price + print ''; + // Value sell + print ''; + else print $langs->trans("Variable"); + print '';; + $total += $obj->reel; + if (price2num($object->pmp)) $totalwithpmp += $obj->reel; + $totalvalue = $totalvalue + ($object->pmp * $obj->reel); + $totalvaluesell = $totalvaluesell + ($object->price * $obj->reel); + // Batch Detail + if ((!empty($conf->productbatch->enabled)) && $object->hasbatch()) { + $details = Productbatch::findAll($db, $obj->product_stock_id, 0, $object->id); + if ($details < 0) dol_print_error($db); + foreach ($details as $pdluo) { + $product_lot_static->id = $pdluo->lotid; + $product_lot_static->batch = $pdluo->batch; + $product_lot_static->eatby = $pdluo->eatby; + $product_lot_static->sellby = $pdluo->sellby; + + if ($action == 'editline' && GETPOST('lineid', 'int') == $pdluo->id) { //Current line edit + print "\n" . ''; + print ''; + } else { + print "\n" . ''; + print ''; + print ''; + print ''; + print ''; + print ''; + } + } } + $i++; + + } + } else dol_print_error($db); + + print ''; + print ''; + print ''; +// Value purchase + print ''; + print ''; +// Value to sell + print ''; + print ""; + print "
'.$formproduct->selectWarehouses('', 'fk_entrepot').'
'.$langs->trans("Warehouse").''.$langs->trans("StockLimit").''.$langs->trans("DesiredStock").'
' . $langs->trans("Warehouse") . '' . $langs->trans("NumberOfUnit") . '' . $langs->trans("AverageUnitPricePMPShort") . '' . $langs->trans("EstimatedStockValueShort") . '' . $langs->trans("SellPriceMin") . '' . $langs->trans("EstimatedStockValueSellShort") . '
' . $langs->trans("batch_number") . '' . $langs->trans("EatByDate") . '' . $langs->trans("SellByDate") . '
'.$ent->getNomUrl(3).''.$line['seuil_stock_alerte'].''.$line['desiredstock'].''.img_delete().'
' . $entrepotstatic->getNomUrl(1) . '' . $stock_real . ($stock_real < 0 ? ' ' . img_warning() : '') . '' . (price2num($object->pmp) ? price2num($object->pmp, 'MU') : '') . '' . (price2num($object->pmp) ? price(price2num($object->pmp * $obj->reel, 'MT')) : '') . ''; + if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($object->price, 'MU'), 1); + else print $langs->trans("Variable"); + print ''; + if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($object->price * $obj->reel, 'MT'), 1) . '
'; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print '
'; + print $form->selectDate($pdluo->eatby, 'eatby', '', '', 1, '', 1, 0); + print ''; + print $form->selectDate($pdluo->sellby, 'sellby', '', '', 1, '', 1, 0); + print '' . $pdluo->qty . ($pdluo->qty < 0 ? ' ' . img_warning() : '') . ''; + print '
'; + print ''; + print '
'; + print img_picto($langs->trans("Tranfer"), 'uparrow', 'class="hideonsmartphone"') . ' '; + print 'id . '">' . $langs->trans("TransferStock") . ''; + // Disabled, because edition of stock content must use the "Correct stock menu". + // Do not use this, or data will be wrong (bad tracking of movement label, inventory code, ... + //print 'id.'#'.$pdluo->id.'">'; + //print img_edit().''; + print $product_lot_static->getNomUrl(1); + print '' . dol_print_date($pdluo->eatby, 'day') . '' . dol_print_date($pdluo->sellby, 'day') . '' . $pdluo->qty . ($pdluo->qty < 0 ? ' ' . img_warning() : '') . '
' . $langs->trans("Total") . ':' . price2num($total, 'MS') . ''; + print ($totalwithpmp ? price(price2num($totalvalue / $totalwithpmp, 'MU')) : ' '); // This value may have rounding errors + print ''; + print $totalvalue ? price(price2num($totalvalue, 'MT'), 1) : ' '; + print ''; + if (empty($conf->global->PRODUIT_MULTIPRICES)) print ($total ? price($totalvaluesell / $total, 1) : ' '); + else print $langs->trans("Variable"); + print ''; + if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($totalvaluesell, 'MT'), 1); + else print $langs->trans("Variable"); + print '
"; + print '
'; + + if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE)) { + print '

'; + print_titre($langs->trans('AddNewProductStockWarehouse')); + + if (!empty($user->rights->produit->creer)) { + print '
'; + print ''; + print ''; + } + print ''; + if (!empty($user->rights->produit->creer)) { + print ''; + print ''; + print ''; + print ''; + print ''; + } else { + print ''; + print ''; + print ''; print ''; } - } - print "
' . $formproduct->selectWarehouses('', 'fk_entrepot') . '
' . $langs->trans("Warehouse") . '' . $langs->trans("StockLimit") . '' . $langs->trans("DesiredStock") . '
"; + $pse = new ProductStockEntrepot($db); + $lines = $pse->fetchAll($id); - if (!empty($user->rights->produit->creer)){ - print '
'; + if (!empty($lines)) { + $var = false; + foreach ($lines as $line) { + $ent = new Entrepot($db); + $ent->fetch($line['fk_entrepot']); + print '' . $ent->getNomUrl(3) . ''; + print '' . $line['seuil_stock_alerte'] . ''; + print '' . $line['desiredstock'] . ''; + if (!empty($user->rights->produit->creer)) { + print '' . img_delete() . ''; + } + print ''; + } + } + + print ""; + + if (!empty($user->rights->produit->creer)) { + print ''; + } } +} else { + // List of variants + + $prodstatic = new Product($db); + $prodcomb = new ProductCombination($db); + $comb2val = new ProductCombination2ValuePair($db); + $productCombinations = $prodcomb->fetchAllByFkProductParent($object->id); + + print '
'; + print ''; + print ''; + print ''; + print ''; + + // load variants + $title = $langs->trans("ProductCombinations"); + + print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', 0); + + print '
'; + ?> + + + + + + + + + + fetch($currcomb->fk_product_child); + $prodstatic->load_stock(); + $stock_total+=$prodstatic->stock_reel; + ?> + + + + + + + + + + '; + print ''; + print ''; + print ''; + } + else + { + print ''; + } + ?> +
trans('Product') ?>trans('Combination') ?>trans('OnSell') ?>trans('OnBuy') ?>trans('Stock') ?>
getNomUrl(1) ?> + fetchByFkCombination($currcomb->id); + $iMax = count($productCombination2ValuePairs); + + for ($i = 0; $i < $iMax; $i++) { + echo dol_htmlentities($productCombination2ValuePairs[$i]); + + if ($i !== ($iMax - 1)) { + echo ', '; + } + } ?> + getLibStatut(2, 0) ?>getLibStatut(2, 1) ?>stock_reel ?> + +
'.$langs->trans("Total").''.$stock_total.'
'.$langs->trans("None").'
+ + '; + + print ''; } // End of page diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index 58eb2178da4..3c94e775ee0 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -634,7 +634,7 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; } $db->commit(); - return 1; + return $newproduct->id; } /** From 58be4ac7a32836d28d7a1df033ba57f02225ebda Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Thu, 11 Oct 2018 12:36:10 +0200 Subject: [PATCH 2/6] New: works with variants: - Hide child products into list if PRODUIT_ATTRIBUTES_HIDECHILD is activated --- htdocs/product/list.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 28f08035198..720ef957c01 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -286,6 +286,11 @@ if (!empty($conf->variants->enabled) && $search_hidechildproducts && ($search_ty $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_combination pac ON pac.fk_product_child = p.rowid"; } +if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) { + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_combination pac ON pac.fk_product_child = p.rowid"; +} + + $sql.= ' WHERE p.entity IN ('.getEntity('product').')'; if ($sall) $sql .= natural_search(array_keys($fieldstosearchall), $sall); // if the type is not 1, we show all products (type = 0,2,3) @@ -294,6 +299,11 @@ if (dol_strlen($search_type) && $search_type != '-1') if ($search_type == 1) $sql.= " AND p.fk_product_type = 1"; else $sql.= " AND p.fk_product_type <> 1"; } + +if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) { + $sql .= " AND pac.rowid IS NULL"; +} + if ($search_ref) $sql .= natural_search('p.ref', $search_ref); if ($search_label) $sql .= natural_search('p.label', $search_label); if ($search_barcode) $sql .= natural_search('p.barcode', $search_barcode); From ab55ff2e2c71218ba84ca6683e64169615620acd Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Thu, 11 Oct 2018 15:44:23 +0200 Subject: [PATCH 3/6] New: works with variants: - Make the checkbox working correctly --- htdocs/langs/en_US/products.lang | 1 + htdocs/product/class/product.class.php | 2 +- htdocs/product/list.php | 37 ++++++++++--------- htdocs/product/stock/product.php | 2 +- .../class/ProductCombination.class.php | 1 + 5 files changed, 24 insertions(+), 19 deletions(-) diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 0dde8ad538a..33be55ec336 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -330,6 +330,7 @@ NbOfDifferentValues=No. of different values NbProducts=No. of products ParentProduct=Parent product HideChildProducts=Hide variant products +ShowChildProducts=Show variant products ConfirmCloneProductCombinations=Would you like to copy all the product variants to the other parent product with the given reference? CloneDestinationReference=Destination product reference ErrorCopyProductCombinations=There was an error while copying the product variants diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 3257f9bbde5..adb17e67235 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4,7 +4,7 @@ * Copyright (C) 2005-2015 Regis Houssin * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2007-2011 Jean Heimburger - * Copyright (C) 2010-2013 Juanjo Menent + * Copyright (C) 2010-2018 Juanjo Menent * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2013-2014 Cedric GROSS * Copyright (C) 2013-2016 Marcos García diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 720ef957c01..9028ceb15c2 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2018 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2012-2016 Marcos García - * Copyright (C) 2013-2016 Juanjo Menent + * Copyright (C) 2013-2018 Juanjo Menent * Copyright (C) 2013-2015 Raphaël Doursenaud * Copyright (C) 2013 Jean Heimburger * Copyright (C) 2013 Cédric Salvador @@ -53,7 +53,7 @@ $sall=trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alp $search_ref=GETPOST("search_ref"); $search_barcode=GETPOST("search_barcode"); $search_label=GETPOST("search_label"); -$search_type = GETPOST("search_type",'int'); +$search_type = GETPOST("search_type", 'int'); $search_sale = GETPOST("search_sale"); $search_categ = GETPOST("search_categ",'int'); $search_tosell = GETPOST("search_tosell", 'int'); @@ -66,11 +66,11 @@ $search_accountancy_code_buy = GETPOST("search_accountancy_code_buy",'alpha'); $optioncss = GETPOST('optioncss','alpha'); $type=GETPOST("type","int"); -//Show/hide child products. Hidden by default -if (!$_POST) { - $search_hidechildproducts = 'on'; +//Show/hide child products +if (!empty($conf->variants->enabled) && ! empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) { + $show_childproducts = GETPOST('show_childproducts'); } else { - $search_hidechildproducts = GETPOST('search_hidechildproducts'); + $show_childproducts = ''; } $diroutputmassaction=$conf->product->dir_output . '/temp/massgeneration/'.$user->id; @@ -219,6 +219,8 @@ if (empty($reshook)) $search_tobuy=""; $search_tobatch=''; //$search_type=''; // There is 2 types of list: a list of product and a list of services. No list with both. So when we clear search criteria, we must keep the filter on type. + + $show_childproducts = ''; $search_accountancy_code_sell=''; $search_accountancy_code_buy=''; $search_array_options=array(); @@ -265,7 +267,7 @@ $sql.= ' p.fk_product_type, p.duration, p.tosell, p.tobuy, p.seuil_stock_alerte, $sql.= ' p.tobatch, p.accountancy_code_sell, p.accountancy_code_sell_intra, p.accountancy_code_sell_export, p.accountancy_code_buy,'; $sql.= ' p.datec as date_creation, p.tms as date_update, p.pmp,'; $sql.= ' MIN(pfp.unitprice) as minsellprice'; -if (!empty($conf->variants->enabled) && $search_hidechildproducts && ($search_type === 0)) { +if (!empty($conf->variants->enabled) && (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD) && ! $show_childproducts )) { $sql .= ', pac.rowid prod_comb_id'; } // Add fields from extrafields @@ -282,11 +284,8 @@ if (! empty($search_categ) || ! empty($catid)) $sql.= ' LEFT JOIN '.MAIN_DB_PREF $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 && ($search_type === 0)) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_combination pac ON pac.fk_product_child = p.rowid"; -} -if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) { +if (!empty($conf->variants->enabled) && (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD) && ! $show_childproducts )) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_combination pac ON pac.fk_product_child = p.rowid"; } @@ -300,7 +299,7 @@ if (dol_strlen($search_type) && $search_type != '-1') else $sql.= " AND p.fk_product_type <> 1"; } -if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) { +if (!empty($conf->variants->enabled) && (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD) && ! $show_childproducts )) { $sql .= " AND pac.rowid IS NULL"; } @@ -318,7 +317,7 @@ 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_buy) $sql.= natural_search('p.accountancy_code_buy', $search_accountancy_code_buy); -if (!empty($conf->variants->enabled) && $search_hidechildproducts && ($search_type === 0)) $sql .= " AND pac.rowid IS NULL"; + // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; // Add where from hooks @@ -328,7 +327,10 @@ $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_sell_intra, p.accountancy_code_sell_export, p.accountancy_code_buy, p.pmp'; -if (!empty($conf->variants->enabled) && $search_hidechildproducts && ($search_type === 0)) $sql .= ', pac.rowid'; + +if (!empty($conf->variants->enabled) && (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD) && ! $show_childproducts )) { + $sql .= ', pac.rowid'; +} // 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 : ''); @@ -402,6 +404,7 @@ if ($resql) if ($search_tobuy != '') $param.="&search_tobuy=".urlencode($search_tobuy); if ($fourn_id > 0) $param.=($fourn_id?"&fourn_id=".$fourn_id:""); if ($seach_categ) $param.=($search_categ?"&search_categ=".urlencode($search_categ):""); + if ($show_childproducts) $param.=($show_childproducts?"&show_childproducts=".urlencode($show_childproducts):""); if ($type != '') $param.='&type='.urlencode($type); if ($search_type != '') $param.='&search_type='.urlencode($search_type); if ($optioncss != '') $param.='&optioncss='.urlencode($optioncss); @@ -477,10 +480,10 @@ if ($resql) } //Show/hide child products. Hidden by default - if (!empty($conf->variants->enabled) && $search_type === 0) { + if (!empty($conf->variants->enabled) && !empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD )) { $moreforfilter.='
'; - $moreforfilter.= ''; - $moreforfilter.= ' '; + $moreforfilter.= ''; + $moreforfilter.= ' '; $moreforfilter.='
'; } diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php index 51871736a3d..dc291eb0fdc 100644 --- a/htdocs/product/stock/product.php +++ b/htdocs/product/stock/product.php @@ -5,7 +5,7 @@ * Copyright (C) 2005 Simon TOSSER * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2013 Cédric Salvador - * Copyright (C) 2013-2015 Juanjo Menent + * Copyright (C) 2013-2018 Juanjo Menent * Copyright (C) 2014-2015 Cédric Gross * Copyright (C) 2015 Marcos García * Copyright (C) 2018 Frédéric France diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index 3c94e775ee0..8908bfa4d2d 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -1,6 +1,7 @@ + * Copyright (C) 2018 Juanjo Menent * * 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 From 0976616401c424a0a5fb3a3faa76f37c65915d67 Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Thu, 11 Oct 2018 17:13:39 +0200 Subject: [PATCH 4/6] Fix: Opening brace should be on a new line --- htdocs/product/class/product.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index adb17e67235..e8dff4c8e92 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -3498,7 +3498,8 @@ class Product extends CommonObject * * @return int Number of variants */ - function hasVariants() { + function hasVariants() + { $nb = 0; $sql = "SELECT count(rowid) as nb FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE fk_product_parent = ".$this->id; $sql.= " AND entity IN (".getEntity('product').")"; From c2814948fbf51f9095956eff7bb584bb5b346127 Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Mon, 15 Oct 2018 11:48:55 +0200 Subject: [PATCH 5/6] Fix: name of fields used into the search criteria must always start with "search_" --- htdocs/product/list.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 9028ceb15c2..36bf5a24ef9 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -68,7 +68,7 @@ $type=GETPOST("type","int"); //Show/hide child products if (!empty($conf->variants->enabled) && ! empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) { - $show_childproducts = GETPOST('show_childproducts'); + $show_childproducts = GETPOST('search_show_childproducts'); } else { $show_childproducts = ''; } @@ -404,7 +404,7 @@ if ($resql) if ($search_tobuy != '') $param.="&search_tobuy=".urlencode($search_tobuy); if ($fourn_id > 0) $param.=($fourn_id?"&fourn_id=".$fourn_id:""); if ($seach_categ) $param.=($search_categ?"&search_categ=".urlencode($search_categ):""); - if ($show_childproducts) $param.=($show_childproducts?"&show_childproducts=".urlencode($show_childproducts):""); + if ($show_childproducts) $param.=($show_childproducts?"&search_show_childproducts=".urlencode($show_childproducts):""); if ($type != '') $param.='&type='.urlencode($type); if ($search_type != '') $param.='&search_type='.urlencode($search_type); if ($optioncss != '') $param.='&optioncss='.urlencode($optioncss); @@ -482,8 +482,8 @@ if ($resql) //Show/hide child products. Hidden by default if (!empty($conf->variants->enabled) && !empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD )) { $moreforfilter.='
'; - $moreforfilter.= ''; - $moreforfilter.= ' '; + $moreforfilter.= ''; + $moreforfilter.= ' '; $moreforfilter.='
'; } From 58cc9aa918435603a8c68cab0f813ed2aeaed8e4 Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Mon, 15 Oct 2018 12:45:40 +0200 Subject: [PATCH 6/6] Fix: found 1 blank lines before brace --- htdocs/product/class/product.class.php | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 5d4cbd8e0bf..442ae55ac3a 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4156,16 +4156,15 @@ class Product extends CommonObject $this->stock_theorique+=$stock_commande_fournisseur-$stock_reception_fournisseur; } - if (! is_object($hookmanager)) { - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager=new HookManager($this->db); - } - $hookmanager->initHooks(array('productdao')); - $parameters=array('id'=>$this->id); - // Note that $action and $object may have been modified by some hooks - $reshook=$hookmanager->executeHooks('loadvirtualstock', $parameters, $this, $action); - if ($reshook > 0) $this->stock_theorique = $hookmanager->resArray['stock_theorique']; - + if (! is_object($hookmanager)) { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('productdao')); + $parameters=array('id'=>$this->id); + // Note that $action and $object may have been modified by some hooks + $reshook=$hookmanager->executeHooks('loadvirtualstock', $parameters, $this, $action); + if ($reshook > 0) $this->stock_theorique = $hookmanager->resArray['stock_theorique']; }